Как я могу сделать замену только в строке первого вхождения матча? - PullRequest
1 голос
/ 03 апреля 2019

У меня есть файл, который выглядит следующим образом

000099990000 Carlos C
000099990000 Ana B
000099990000 Ana A Test
000099990000 Ana B
000099990000 Carlos C

Я хочу найти только первое вхождение Ana B, а затем заменить 9999 часть соответствующей строки на 1111.

Я запускаю следующую строку:

sed -i '0,/Ana B/ s/9999/1111/' file.txt

, но получаю следующий результат:

000011110000 Carlos C
000011110000 Ana B
000099990000 Ana A Test
000099990000 Ana B
000099990000 Carlos C

Итак, sed заменяет все строки допервое вхождение Ana B.Что не так с моей командой?

1 Ответ

2 голосов
/ 03 апреля 2019
$ sed '0,/Ana B/ { //s/9999/1111/ }' ip.txt
000099990000 Carlos C
000011110000 Ana B
000099990000 Ana A Test
000099990000 Ana B
000099990000 Carlos C
  • { //s/9999/1111/ } {} здесь позволяет группировать команды для выполнения только при выполнении условия 0,/Ana B/
  • // будет повторно использовать последнее использованное регулярное выражение, так же как и при использовании/Ana B/ - это обеспечит изменение только строк, содержащих Ana B


Вы также можете использовать awk здесь:

$ awk '/Ana B/ && !c++{sub(/9999/, "1111")} 1' ip.txt
000099990000 Carlos C
000011110000 Ana B
000099990000 Ana A Test
000099990000 Ana B
000099990000 Carlos C
  • /Ana B/ && !c++, если строка содержит Ana B и c равно нулю (значение по умолчанию для неинициализированных переменных)
    • , поскольку ++ в следующий раз c будет 1 иусловие не будет выполнено (обратите внимание, что очень большое совпадение Ana B может привести к переполнению и c снова становится 0)
  • sub(/9999/, "1111") изменить 9999 на 1111
  • 1 идиоматический способ печати содержимого $0 (входная запись)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...