Как пропустить строки, соответствующие строке - PullRequest
7 голосов
/ 13 июля 2011

Я новичок в седе, так что, возможно, кто-то может мне помочь.Я изменяю некоторые файлы и хочу пропустить все строки, содержащие строки «def» или «page».на них.Как мне это сделать в sed?

Ответы [ 2 ]

18 голосов
/ 14 июля 2011

Если я правильно понял, вы хотите применить некоторые изменения к различным строкам, кроме строки, соответствующей регулярному выражению, верно? В этом случае предположим, что у меня есть следующий файл:

$ cat file
this is a def
this has no d e f
this is a page by the way
but this is no p a g e as we know ito

Мы хотим заменить все this на that, но игнорируем строки, содержащие def или page. Итак, сначала мы удаляем строки, начинающиеся с def или page:

/def/d;/page/d;

Затем мы применяем нашу операцию как обычно:

s/this/that/g

Результат:

$ sed '/def/d;/page/d;s/this/that/g' file
that has no d e f
but that is no p a g e as we know ito

Но если под "пропустить" вы имеете в виду "не применять мои операции", просто отрицайте адрес:

$ sed -E '/(def|page)/!s/this/that/g' file
this is a def
that has no d e f
this is a page by the way
but that is no p a g e as we know ito

Вышеприведенное утверждение верно. Интересно, что оператор «или» связан с «расширенным регулярным выражением». Поэтому вы должны указать -E для «расширенного регулярного выражения», потому что sed по умолчанию использует только «базовые регулярные выражения».

Например, следующий оператор не работает:

$ sed -e '/(def|page)/!s/[A-Za-z_]*login[A-Za-z_]*/page.&/g' < file > new_file

Но это утверждение ниже работает:

$ sed -E '/(def|page)/!s/[A-Za-z_]*login[A-Za-z_]*/page.&/g' < file > new_file
1 голос
/ 14 июля 2011

AFAIK Вы не можете (легко) отрицать совпадающие строки с помощью sed, но что-то вроде этого почти сработает:

sed '/\([^d][^e][^f][^ ]\)\|\([^p][^a][^g][^e]\)/ s/foo/bar/' FILE

заменяет foo на bar в строках, которые не содержат def или page, но уловка заключается в том, что "совпадающие" строки должны быть длиной не менее 4 символов.

Лучшее решение - использовать awk, например ::

awk '{ if ($0 !~ /def|page/) { print gensub("foo","bar","g") } else { print } }' FILE

НТН

...