br sed: insere texto após o N-ésimo caractere anterior / seguinte a uma dada string

3

Usando sed , como um texto seria inserido após um caractere que preceda (ou siga) alguma sequência por N ocorrências. Como exemplo, suponha que a linha de texto a ser editada seja a seguinte:

command -some -args -c 'a quoted section;some;lines;of code;keyword;more lines;etc();'

Depois de encontrar essa linha em um arquivo de texto (talvez através da única string command ), desejo inserir texto após o segundo (N = 2) ponto e vírgula antes de keyword (ou seja, o ponto-e-vírgula separando lines e %código%). Eu gostaria especificamente de usar of para o propósito.

Continuando com este exemplo, a saída esperada seria:

command -some -args -c 'a quoted section;some;lines;INSERTED_STRING;of code;keyword;more lines;etc();'

onde sed (fornecido para sed, por exemplo, via uma variável shell) foi inserido na posição desejada.

    
por user001 10.11.2017 / 09:47

3 respostas

2

Eu o mantenho simples:

sed '/command/s/[^;]*;keyword/INSERTED_STRING;&/'

para inserir dois campos antes da palavra-chave. A solução geral seria

sed "/command/s/\([^;]*;\)\{$N\}keyword/INSERTED_STRING;&/"

mas observe que o N tem uma rede de 1 em comparação com a sua pergunta: Aqui, N=2 significa ter dois campos entre a inserção e o keyword .

Explicação: /command/ seleciona apenas linhas com command , portanto outras linhas permanecem inalteradas. ([^;]*;\) corresponde a um campo (uma sequência de semicolons) incluindo o ponto e vírgula a seguir. Seguindo-o com \{$N\} , o padrão corresponde a $N fields. O seguinte keyword conclui isso para corresponder aos campos keyword e $N antes. O padrão de substituição consiste na string inserida e & , que é substituído por tudo que foi correspondido (então, no final, não foi uma substituição, mas uma inserção).

Em curto e melhor legível com expressões regulares estendidas:

sed -E "/command/s/([^;]*;){$N}keyword/INSERTED_STRING;&/"
    
por 10.11.2017 / 10:39
2

Usando sed , você pode alterar apenas a terceira ocorrência do seu padrão, que é ponto-e-vírgula aqui.

sed 's/;/;INSERTED_STRING;/3' <<<"$string"

Editar: Para substituir N th a ocorrência de uma string antes de outra Pattern String keyword ("ocorrência relativa", no seu caso 2 nd ocorrência) se as linhas coincidirem com uniqe command string.):

sed -r '/command/ s/([^;]*;){1}keyword/INSERTED_STRING;&/' <<<"$string"
    
por 10.11.2017 / 10:00
0

Se você vir os bits ; -delimited como campos de um registro, poderá fazer isso com awk da seguinte forma:

$ awk -F';' -vOFS=';' -vstring="NEW TEXT" '{ $4 = $4 ";" string; print }' file
command -some -args -c 'a quoted section;some;lines;of code;NEW TEXT;keyword;more lines;etc();'

awk , com -F';' , divide a linha em file em vários campos ; -delimited. O código então modifica o quarto campo adicionando um ; extra e a string mantida na variável string (definida na linha de comando), e gera os dados com o campo modificado. A saída também seria ; -delimited.

    
por 10.11.2017 / 10:53

Tags