Sed: Substituir o padrão em cada segunda nova linha?

9

Existe uma maneira de informar sed para substituir o padrão em cada segunda ocorrência? Ou pelo menos em cada segunda linha? (Claro que é possível com um script, mas eu estava me perguntando se sed pode fazer isso).

Editar

Eu encontrei

sed -e "s/pattern/replacement/g;n"

Mas substituiu cada primeira ocorrência, não a segunda.

    
por Matthieu Riegler 01.08.2012 / 13:35

4 respostas

7

veja link

A solução usa awk ao invés de sed, mas "use a ferramenta certa para o trabalho". Pode ou não ser possível fazer em sed mas, mesmo se for, será um lote mais fácil em uma ferramenta como awk ou perl.

    
por 01.08.2012 / 14:22
12

sed 's/pattern/replacement/2'

Substituirá a segunda ocorrência em todas as linhas que tiverem o padrão.

se você tem o GNU sed:

sed '1~2N ; s/pattern/replacement/2' Starting from line one 1, the line after it will be added to the pattern space N then the s command will replace the second occurrence of the pattern. then sed will move two lines down ~2 and repeat.

    
por 01.08.2012 / 13:44
1

A interpretação simples:

Na primeira linha que contém pelo menos uma ocorrência de PATTERN, você deseja ignorá-la e imprimir a linha como está. Na segunda linha que contém pelo menos uma ocorrência de PATTERN você deseja substituir a primeira instância de PATTERN por REPLACEMENT. Na terceira linha que contém pelo menos uma ocorrência de PATTERN você deseja imprimir a linha como está. Na quarta linha que contém pelo menos uma ocorrência de PATTERN você deseja substituir a primeira instância de PATTERN por REPLACEMENT. E assim por diante. Linhas que não combinam com PADRÃO devem ser impressas sem alteração.

Isso pode ser feito facilmente com o Sed assim:

sed -e '/PATTERN/ { :inside' -e 'n;s//REPLACEMENT/;t' -e 'b inside' -e '}'

Ou com menos espaço em branco e um rótulo mais curto:

sed -e '/PATTERN/{:i' -e 'n;s//REPLACEMENT/;t' -e 'b i' -e '}'

EDIT: Eu apenas reli a pergunta e vi a interpretação mais difícil:

Substitua a segunda ocorrência de PATTERN no documento inteiro por REPLACEMENT, independentemente de ocorrer na mesma linha da primeira ocorrência ou não. Deixe a primeira e a terceira ocorrências inalteradas. Etc.

Eu acredito que isso pode ser feito com Sed também, embora seja MUITO mais complicado e eu acredito que seja dependente da expressão regular a ser usada. Vou tentar resolver algo e publicá-lo, mas deixarei essa resposta com a versão simples acima, por enquanto.

    
por 11.10.2016 / 11:07
0

Um padrão de símbolo dentro de uma linha:     sed 's / (a [^ a] *) a / \ 1c / g'

A cada segundo padrão (apenas uma correspondência de padrão por linha pode aparecer. Se duas ou mais correspondências por uma linha aparecer, somente a segunda será substituída)

echo -e "test\nreplace_me\ntest\ntest\nreplace_me\nreplace_me\nreplace_me" | \
sed '/replace_me/{:a;N;/replace_me.*replace_me/!Ta;s/replace_me/replaced/2;}'
    
por 01.08.2012 / 14:28

Tags