Я склонен использовать 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/
), она просто печатается.
Для строк, которые соответствуют шаблону, печатаются все, если установлен флаг 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
29.06.2011
-v
для передачи переменных оболочки в виде переменныхawk
- смотрите обновление. 29.06.2011sed
, а неawk
. Приведенное ниже решение дляsed
намного проще и дает желаемый результат гораздо короче. @paxdiablo упоминает об использованииawk
для работы над более сложными задачами. Удалить первое вхождение регулярного выражения вряд ли сложно, и фактически в этом случае использованиеawk
делает его таким. 07.03.2014