Сценарий Linux SED находит первую строку, соответствующую шаблону, и удаляет ее - PullRequest
3 голосов
/ 29 июня 2011

Я хочу создать команду sed, чтобы найти в файле 1-ю строку, которая соответствует шаблону, и удалить всю эту строку или заменить ее другим текстом. Я не хочу сопоставлять всю строку, потому что правило состоит в том, чтобы соответствовать ее части.

как я могу сделать это с помощью sed?

например:

myline 1 is pretty
line 2 is ugly
myline 111 is nice

Я хочу удалить первую строку, содержащую «1 is»

ОБНОВЛЕНИЕ: в моей строке могут быть такие символы, как "/" и "<" </p>

С уважением Фак

Ответы [ 3 ]

7 голосов
/ 29 июня 2011

Из sed FAQ :

sed '0,/RE/{//d;}' file        # delete only the first match
sed '0,/RE/s//to_that/' file   # change only the first match

Если вы не используете GNU sed, найдите альтернативы в FAQ.

1 голос
/ 29 июня 2011

Я склонен использовать awk для более сложных задач, он немного мощнее, чем sed, с правильными конструкциями циклов и выбора (расширен для удобства чтения, вы можете сжать его обратно до одной строки, если хотите):

pax$ echo '
xyz
myline 1 is pretty
line 2 is ugly
myline 111 is nice'  | awk '
     /1 is/ {if (f) {print} else {f = 1}}
    !/1 is/ {print}'

xyz
line 2 is ugly
myline 111 is nice

Для любой строки не , соответствующей шаблону (!/1 is/), он просто печатает ее.

Для строк, которые do соответствуют шаблону, он печатает их все, если установлен флаг f (изначально он не установлен). Когда флаги не установлены, и он сталкивается с соответствующей строкой, он устанавливает флаг и не печатает его. Это в основном удаляет первую совпадающую строку по желанию.

Если вы хотите изменить первую подходящую строку, а не удалять ее, вы просто вставляете код рядом с f = 1, чтобы сделать это, что-то вроде:

pax$ echo '
xyz
myline 1 is pretty
line 2 is ugly
myline 111 is nice'  | awk '
     /1 is/ {if (f) {print} else {f = 1;print "URK!!!"}}
    !/1 is/ {print}'

xyz
URK!!!
line 2 is ugly
myline 111 is nice

Чтобы использовать переменную оболочки в awk, вы можете использовать опцию -v, чтобы передать ее как действительную переменную awk:

pax$ export xyzvar=URK ; echo '
xyz
myline 1 is pretty
line 2 is ugly
myline 111 is nice'  | awk -vmyvar=$xyzvar '
     /1 is/ {if (f) {print} else {f = 1;print myvar}}
    !/1 is/ {print}'

xyz
URK
line 2 is ugly
myline 111 is nice
0 голосов
/ 29 июня 2011

Вы можете сделать это без sed. Bash скрипт:

LINE=$(grep -n "$EXPR" "$FILE" |head -1 |cut -f1 -d:)
head -$(expr $LINE - 1 ) $FILE
tail +$(expr $LINE + 1 ) $FILE

Просто объявите $EXPR и $FILE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...