Попробуйте это:
#!/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"
Этот пример входного файла процесса, который не содержит определение (первой )строки, а идентификатор и группа указаны без кавычек
Это удалит пустые строки с начала, , но не с конца файла. [Обратите внимание, :этот ответ был написан до редактирования вопроса , в котором упоминалось 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
), мы печатаем только строки между (и включая )идентифицированные таким образом первую и последнюю не-пустые строки. Уведомление
Как указано в ответе Стефана Шазела , подход с двумя -проходами работает только с обычными файлами. Если ваш ввод носит другой характер, см. предложенный там метод для решения.
Использование этой техники для удаления пустых строк как из начала, так и из конца файла:
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
Если вы не возражаете против затирания пробелов или табуляций в пустых строках, которые вы хотите сохранить, это удалит пустые строки с начала и конца:
awk 'NF{for(;c;--c)print "";print;x=1;next} x{++c}'
Он подсчитывает количество пустых строк между непустыми строками и печатает это количество пустых строк перед каждой непустой строкой.
Мы можем удалить как начальные, так и конечные пустые строки с помощью следующего кода POSIX -. Начальные пустые строки удаляются с помощью оператора диапазона, который срабатывает только при обнаружении непустой строки. Для конечных строк мы начинаем накапливать пустые строки до тех пор, пока не увидим конец (, в котором мы быстро удаляем этот набор завершающих пустых строк ), или не находим непустую строку (, в которой мы печатаем этот набор по крайней мере из одной пустой + ровно одна непустая строка ).
sed -e '
/./,/^$/!d
/./b
:a
$d;N
/\n$/ba
' file
Что делает ваш код и почему он удаляет только пустые строки в начале ввода, уже было объяснено, например, в ответе @AdminBee , но здесь для полноты картины я предложу альтернативный метод для удаление как начальных, так и конечных пустых строк без необходимости выполнять два прохода по файлу (, что будет работать только для обычных файлов, а не для произвольного ввода ).
awk '
NF {print saved $0; saved = ""; started = 1; next}
started {saved = saved $0 ORS}' < file
Когда мы откладываем печать пустых строк до следующей не -пустой строки, мы видим потом (при условии, что мы уже видели по крайней мере одну не -пустую строку до ).
пример файла
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