Замена первого вхождения в файле
Если я понимаю ваш вопрос и вы хотите найти первую строку в файле, которая соответствует ^[a-z0-9]+ ALL=(ALL) ALL
, и заменить ^[a-z0-9]+ ALL
на что-то вроде^ABC
используя Расширенное регулярное выражение , вы можете использовать:
sed -r '0,/[a-z0-9]+/s/^[a-z0-9]+ ALL(=\(ALL\) ALL.*$)/^ABC\1/'
Просмотр некомментированных строк в /etc/sudoers
с доступом sudo
, предоставленным членам группы wheel
, вы должны иметь:
$ noc /etc/sudoers
root ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
%wheel ALL=(ALL) NOPASSWD: ALL
Таким образом, чтобы заменить первую строку на [a-z0-9]+ ALL=(ALL) ALL
в /etc/sudoers
на ^ABC=(ALL) ALL
, вы должны:
$ noc /etc/sudoers | sed -r '0,/[a-z0-9]+/s/^[a-z0-9]+ ALL(=\(ALL\) ALL.*$)/^ABC\1/'
^ABC=(ALL) ALL
%wheel ALL=(ALL) ALL
%wheel ALL=(ALL) NOPASSWD: ALL
Редактировать в-Комментарий
В своем комментарии вы говорите, что хотите найти "<string> ALL=(ALL) ALL
, где string
может быть всем, но не 'ALL'
".Так как sed
не поддерживает просмотр вперед или назад, лучшее, что вы можете сделать, это явно не соответствовать ALL
в начале строки.Это означает, что вы хотите найти строки, начинающиеся ^[^A][^L][^L]
.Хотя это несколько ограничительно, он будет искать строку, которая не начинается с "ALL"
, но это может быть вашим единственным выходом.Например:
sed -r '0,/^[^A][^L][^L]/s/^[^A][^L][^L][^ ]+( ALL=\(ALL\) ALL.*$)/^ABC\1/'
Снова возьмите пример файла sudoers
и включите ALL ALL=(ALL) ALL
, который вы не хотите сопоставлять, например,
$ cat sudoers
ALL ALL=(ALL) ALL
root ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
%wheel ALL=(ALL) NOPASSWD: ALL
Теперь примените выражение, определяющее первый <string>
не ALL
в <string> ALL=(ALL) ALL
и вы получите:
$ sed -r '0,/^[^A][^L][^L]/s/^[^A][^L][^L][^ ]+( ALL=\(ALL\) ALL.*$)/^ABC\1/' sudoers
ALL ALL=(ALL) ALL
^ABC ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
%wheel ALL=(ALL) NOPASSWD: ALL
Заменить пронумерованное вхождение в строке
Если вы хотите заменить вхождениев пределах линии.С расширенным регулярным выражением, используя s/find/replace/n
, где n=1,2,3..
- это вхождение шаблона find
для замены, вы можете заменить первое вхождение, например,
sed -r 's/[0-9a-z]+/cde456/1'
Например:
$ echo "abc123---abc123---abc123" | sed -r 's/[0-9a-z]+/cde456/1'
cde456---abc123---abc123
Или для замены второго вхождения вы должны использовать:
$ echo "abc123---abc123---abc123" | sed -r 's/[0-9a-z]+/cde456/2'
abc123---cde456---abc123
Такое же сопоставление вхождений доступно для базовых регулярных выражений, у вас просто нет '+'
(соответствует одному или нескольким вхождениям), необходимо ли изменить шаблон find
, например
sed 's/[0-9a-z][0-9a-z]*/cde456/1`
, чтобы заменить искомое вхождение без использования расширенного регулярного выражения.