Команда Sed для удаления определенных элементов в файле - PullRequest
0 голосов
/ 15 октября 2019

Возможно, подобные вопросы уже задавались ранее, но я не могу найти решение этой проблемы:

Файл, в котором мне нужно удалить строки:

#includedir /etc/sudoers.d
%wheel  ALL=(ALL)       NOPASSWD: ALL
pam_ansible ALL=(ALL) NOPASSWD: ALL
awx ALL=(ALL) NOPASSWD: ALL
***f10222 ALL=(ALL) NOPASSWD: ALL
mn2345zp ALL=(ALL) NOPASSWD: ALL
ab1235xy ALL=(ALL) NOPASSWD: ALL***

Примечание: *** указывает на ту часть, которую я хочу удалить ... *** в действительности не существует в файле.

Я просто хочу удалить строки такого типа, выделенные жирным шрифтом(или между ***) для нескольких файлов, рассматривая этот файл как один из них.

Что может быть sed для таких строк? чтобы удалить его и иметь только оставшееся содержимое:

#includedir /etc/sudoers.d
%wheel  ALL=(ALL)       NOPASSWD: ALL
pam_ansible ALL=(ALL) NOPASSWD: ALL
awx ALL=(ALL) NOPASSWD: ALL

Я новичок с этими командами, я попробую: В моем скрипте я попытался добавить

sed '/[a-z0-9]/d' $user

, где пользователь содержитсписок элементов между ***, но он показывает только

sed: невозможно прочитать: нет такого файла или каталога

Ответы [ 3 ]

1 голос
/ 16 октября 2019

просто попробуйте это ..

  sed '/\*\*\*/,/\*\*\*/d' inputfile

он удалит все между этими двумя паттернами, даже включая эти паттерны, и может обрабатывать те случаи, когда *** находится в середине строки.

0 голосов
/ 16 октября 2019

В случае если вы в порядке с awk, не могли бы вы попробовать следующее.

awk '$1 ~ /[a-zA-Z]/ && $1 !~ /[0-9]/' Input_file > temp && mv temp Input_file
0 голосов
/ 16 октября 2019

Учитывая, что *** отображается в середине строки, может быть несколько вариантов в зависимости от характеристик входного файла.

Если в каждом файле содержится не более одного закрытого блока, пожалуйста,try:

sed -i '
:l      ;# defines a label
N       ;# reads the next line and appends it to the pattern space
$!bl    ;# goes back to the label until the EOF
s/\*\*\*.*\*\*\*//      ;# removes the block between *** and ***
s/\n$//                 ;# removes a trailing newline if any
' input.txt

Если какой-либо из файлов может содержать несколько блоков, которые нужно удалить, приведенная выше команда sed не работает должным образом из-за greedy (longest) match.
В этом случае обходной путьбудет использовать Perl, регулярное выражение которого поддерживает non-greedy match:

perl -0777 -pi -e 's/\*\*\*.*?\*\*\*\n?//sg' input.txt

Надеюсь, это поможет.

...