С помощью sed или awk переместите шаблон соответствия строк в конец файла

У меня похожая проблема. Мне нужно переместить строку в / etc / sudoers в конец файла.

Строка, которую я хочу переместить:

#includedir /etc/sudoers.d 

Я пробовал с переменной

#creates variable value
templine=$(cat /etc/sudoers | grep "#includedir /etc/sudoers.d")

#delete value
sed '/"${templine}"/d' /etc/sudoers

#write value to the bottom of the file
cat ${templine} >> /etc/sudoers

Не получаю ни ошибок, ни результата, который я ищу.

Какие-либо предложения?

Всего 4 ответа


С awk:

awk '$0=="#includedir /etc/sudoers.d"{lastline=$0;next}{print $0}END{print lastline}' /etc/sudoers

Это говорит:

  1. Если строка $0 имеет вид "#includedir /etc/sudoers.d" тогда установите для переменной lastline значение этой строки $0 и перейдите к следующей строке.
  2. Если вы все еще здесь, выведите строку {print $0}
  3. После обработки каждой строки в файле выведите все, что находится в переменной lastline .

Пример:

$ cat test.txt
hi
this
is
#includedir /etc/sudoers.d
a
test
$ awk '$0=="#includedir /etc/sudoers.d"{lastline=$0;next}{print $0}END{print lastline}' test.txt
hi
this
is
a
test
#includedir /etc/sudoers.d

Вы можете сделать все это с помощью sed :

sed -e '/#includedir .etc.sudoers.d/ { h; $p; d; }' -e '$G' /etc/sudoers

Это может работать для вас (GNU sed):

sed -n '/regexp/H;//!p;$x;$s/.//p' file

Это удаляет строки, содержащие указанное регулярное выражение, и добавляет их в конец файла.

Чтобы переместить только первую строку, соответствующую регулярному выражению, используйте:

sed -n '/regexp/{h;$p;$b;:a;n;p;$!ba;x};p' file

При этом используется цикл для чтения / печати оставшейся части файла, а затем для добавления совпавшей строки.


Если у вас есть несколько записей, которые вы хотите переместить в конец файла, вы можете сделать следующее:

awk '/regex/{a[++c]=$0;next}1;END{for(i=1;i<=c;++i) print a[i]}' file

или же

sed -n '/regex/!{p;ba};H;:a;${x;s/.//;p}' file