Как `awk 'NF {p=1} p' `удаляет пустые строки из начала и конца файла?

Попробуйте это:

    #!/bin/bash

input_file="$1"
base_dir="$2"
delim=","

while read -r line
do
    id=${line%$delim*}
    group=${line#*$delim}
    mv *"${id}"* "$base_dir//$group"
done < "$input_file"

Этот пример входного файла процесса, который не содержит определение (первой )строки, а идентификатор и группа указаны без кавычек

5
23.07.2021, 18:47
6 ответов

Это удалит пустые строки с начала, , но не с конца файла. [Обратите внимание, :этот ответ был написан до редактирования вопроса , в котором упоминалось tac]

Это работает следующим образом:

  • NF— количество полей, найденных в текущей строке. Если он равен нулю, это означает, что строка либо пуста, либо пуста , т.е. содержит не более пробела (, предполагая, что разделитель полей оставлен со значением по умолчанию, где любое количество последовательных пробелов считается разделителем. ).
  • Текущая строка выводится, если какое-либо условие за пределами (и не связанное с )блоками правил({... })оценивается как true. Флаг pизначально не инициализирован и оценивается как false.так что априори ничего печататься не будет.
  • Как только найдена не -пустая строка,(NFне является -нулем и оценивается как true), вводится блок правил {p=1}и флаг pустанавливается на 1. После этого pза пределами блока правил оценивается как true, и печатаются все последующие строки (, включая текущую, первую не -пустую ).

Обратите внимание , что, поскольку флаг pникогда не сбрасывается, любые пустые строки, идущие после первой не-пустой строки, будут напечатаны без фильтрации. Если вы хотите также удалить пустые строки с конца, потребуется двухпроходный -подход:

awk 'FNR==NR{if (NF) {if (!first) first=FNR; last=FNR} next}
     FNR>=first && FNR<=last' input.txt input.txt

Это обработает файл дважды (, следовательно, он указан дважды как операнд)

  • В первом проходе, где FNR, счетчик строк файла -равен NR, общему счетчику строк, мы идентифицируем первую и последнюю не-пустую строку.
  • Во втором проходе(FNRтеперь меньше, чем NR), мы печатаем только строки между (и включая )идентифицированные таким образом первую и последнюю не-пустые строки.

Уведомление

Как указано в ответе Стефана Шазела , подход с двумя -проходами работает только с обычными файлами. Если ваш ввод носит другой характер, см. предложенный там метод для решения.

14
28.07.2021, 11:25

Использование этой техники для удаления пустых строк как из начала, так и из конца файла:

awk 'NF {p=1} p' file | # remove blank lines at the file head
  tac |                 # reverse the lines
  awk 'NF {p=1} p' |    # remove blanks from the "new head"
  tac |                 # re-reverse the file
  sponge file           # from the `moreutils` package, to overwrite the file
5
28.07.2021, 11:25

Если вы не возражаете против затирания пробелов или табуляций в пустых строках, которые вы хотите сохранить, это удалит пустые строки с начала и конца:

awk 'NF{for(;c;--c)print "";print;x=1;next} x{++c}'

Он подсчитывает количество пустых строк между непустыми строками и печатает это количество пустых строк перед каждой непустой строкой.

2
28.07.2021, 11:25

Мы можем удалить как начальные, так и конечные пустые строки с помощью следующего кода POSIX -. Начальные пустые строки удаляются с помощью оператора диапазона, который срабатывает только при обнаружении непустой строки. Для конечных строк мы начинаем накапливать пустые строки до тех пор, пока не увидим конец (, в котором мы быстро удаляем этот набор завершающих пустых строк ), или не находим непустую строку (, в которой мы печатаем этот набор по крайней мере из одной пустой + ровно одна непустая строка ).

sed -e '
  /./,/^$/!d
  /./b
  :a
    $d;N
  /\n$/ba
' file
2
28.07.2021, 11:25

Что делает ваш код и почему он удаляет только пустые строки в начале ввода, уже было объяснено, например, в ответе @AdminBee , но здесь для полноты картины я предложу альтернативный метод для удаление как начальных, так и конечных пустых строк без необходимости выполнять два прохода по файлу (, что будет работать только для обычных файлов, а не для произвольного ввода ).

awk '
       NF {print saved $0; saved = ""; started = 1; next}
  started {saved = saved $0 ORS}' < file

Когда мы откладываем печать пустых строк до следующей не -пустой строки, мы видим потом (при условии, что мы уже видели по крайней мере одну не -пустую строку до ).

4
28.07.2021, 11:25

пример файла

foo = 1700; goo = 1800
pravee

ajay
koy
ram

Пустые строки на 1,4,8

Так как нам нужно удалить пустые строки в первой и последней строке

а. сначала мы находим последнее вхождение пустой строки, используя команду ниже, и присваиваем переменной

lastemptyline=$(awk '/^$/{x=$0}END{print NR}' file)

б. затем мы будем использовать команду sed для удаления первой и последней строки

sed -i -e "1{/^$/d}" -e "$lastemptyline{/^$/d}" file

выход

foo = 1700; goo = 1800
pravee
    
ajay
koy
ram
0
28.07.2021, 11:25

Теги

Похожие вопросы