Como adicionar texto após a enésima ocorrência no bash?

Como adicionar texto após a enésima ocorrência no bash?

Digamos que eu tenha helloworld.txt:

hello world

Usando sed:

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

Me dá:

goodbyehello world

E:

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

Me dá:

hello worldgoodbye

Mas como faço para adicionar textodepoisa primeira ocorrência, então fica assim:

hellogoodbye world

Responder1

Supondo que você esteja falando sobre inserir texto antes ou depois de ocorrências específicas depalavrasem uma linha de texto.

$ 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

Isso insere a string newword(e um espaço anterior) em locais diferentes na string fornecida.

A sedexpressão

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

substituirá a segunda correspondência de uma string não vazia consistindo apenas de caracteres alfanuméricos.

O flanqueamento \<e \>corresponde ao limite de largura zero entre uma palavra e uma não-palavra no início e no final da correspondência, respectivamente (em GNU sed, você também pode usar \bpara estes). Isso garante que você combine palavras inteiras, mas não é realmente necessário com os dados fornecidos (eu uso os padrões de limite de palavras porque enfatiza a intenção do que estou fazendo).

O \{1,\}é um modificador escrito +em uma expressão regular estendida e faz com que o padrão anterior corresponda pelo menos uma vez (mas sedusa expressões regulares básicas por padrão).

Na parte de substituição, &estará o bit da string de entrada que realmente corresponde ao padrão, e no 2final está um sinalizador que faz a substituição acontecer apenas para a segunda correspondência não sobreposta.

Os exemplosno seu comentário(que é quase igual, mas sem inserir o espaço):

$ 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

Observe que no exemplo que você deu nos comentários, as "palavras" também contém travessões, por isso uso [[:alnum:]-]em vez de apenas [[:alnum:]].

informação relacionada