Как добавить текст после n-го вхождения в bash?

Как добавить текст после n-го вхождения в bash?

Допустим, у меня есть helloworld.txt:

hello world

Используя sed:

sed 's/w*/goodbye/' helloworld.txt

Дает мне:

goodbyehello world

И:

sed 's/$/goodbye/' helloworld.txt

Дает мне:

hello worldgoodbye

Но как мне добавить текст?послепервое появление, поэтому выглядит это так:

hellogoodbye world

решение1

Предположим, что вы говорите о вставке текста до или после определенных вхожденийсловав строке текста.

$ echo 'word1 word2 word3 word4' | sed 's/\<[[:alnum:]]\{1,\}\>/newword &/'
newword word1 word2 word3 word4
$ echo 'word1 word2 word3 word4' | sed 's/\<[[:alnum:]]\{1,\}\>/& newword/'
word1 newword word2 word3 word4
$ echo 'word1 word2 word3 word4' | sed 's/\<[[:alnum:]]\{1,\}\>/& newword/2'
word1 word2 newword word3 word4
$ echo 'word1 word2 word3 word4' | sed 's/\<[[:alnum:]]\{1,\}\>/& newword/3'
word1 word2 word3 newword word4
$ echo 'word1 word2 word3 word4' | sed 's/\<[[:alnum:]]\{1,\}\>/& newword/4'
word1 word2 word3 word4 newword

Это вставляет строку newword(и предшествующий ей пробел) в разные места заданной строки.

Выражениеsed

s/\<[[:alnum:]]\{1,\}\>/& newword/2

заменит второе совпадение непустой строки, состоящей только из буквенно-цифровых символов.

Флангирование \<и \>соответствует границе нулевой ширины между словом и не-словом в начале и конце совпадения соответственно (в GNU sedвы также можете использовать \bдля этого). Это гарантирует, что вы сопоставляете целые слова, но на самом деле не нужно с заданными данными (я использую шаблоны границ слов, потому что это подчеркивает намерение того, что я делаю).

— это \{1,\}модификатор, который записывается +в расширенном регулярном выражении и заставляет предыдущий шаблон совпадать по крайней мере один раз (но sedпо умолчанию использует базовые регулярные выражения).

В заменяемой части &будет бит входной строки, который фактически соответствует шаблону, а 2в конце — флаг, который заставляет замену выполняться только для второго неперекрывающегося совпадения.

Примерыв вашем комментарии(что почти то же самое, но без пробела):

$ echo '7DF258 01DB-MET-RX PASS' | sed 's/\<[[:alnum:]-]\{1,\}\>/&FIDUCIAL/'
7DF258FIDUCIAL 01DB-MET-RX PASS
$ echo '7DF258 01DB-MET-RX PASS' | sed 's/\<[[:alnum:]-]\{1,\}\>/&FIDUCIAL/2'
7DF258 01DB-MET-RXFIDUCIAL PASS

Обратите внимание, что в примере, который вы привели в комментариях, «слова» также содержат тире, поэтому я использую , [[:alnum:]-]а не просто [[:alnum:]].

Связанный контент