É possível combinar vários números de linha específicos (sem intervalo) com sed?

8

Considere:

echo -e "a\nb\nc\nd\ne\nf\ng\nh" | sed '3,5a test'

Isso corresponderá às linhas 3, 4 e 5.

Mas estou tentando corresponder apenas às linhas 3 e 5 (não 4). E acrescente 'teste' depois deles.

    
por Aquarius Power 28.02.2014 / 18:08

3 respostas

8
echo ... | sed -e '3a test' -e '5a test'

Se a operação é mais complexa do que neste caso, você pode usar uma estrutura como esta:

sed 'b pattern; : action; a \
lalala
b end; : pattern; 3b action; 5b action; : end'

Ou seja. você coloca todos os comandos necessários entre b pattern; e b end; .

E você adiciona todos os seus padrões (números de linha ou qualquer outro) depois de : pattern; .

O que acontece é isto:

  1. O primeiro comando salta sobre a parte de ação (talvez seja mais fácil de ler se os padrões estiverem no início e b end; diretamente antes da parte de ação).

  2. Se um padrão coincide, a execução vai para a parte de ação. Após a execução da parte de ação, salta para o final.

Eu tento arrumar isso:

sed '3b action; 5b action; b end; : action; a \
lalala
: end'

Em uma única linha, seria como:

sed "3b idAction; 5b idAction; b; : idAction; a test"

Portavelmente, você precisa escrever:

sed '
   3b action
   5b action
   b
   : action
   a\
   lalala'

( b sem ramificações de rótulo até o final, para que você não precise de um rótulo end explícito, ; é um caractere válido em um rótulo nas implementações sed padrão).

    
por 28.02.2014 / 18:12
5

Com sed (consulte a resposta do @HaukeLaging

com awk :

$ echo -e "a\nb\nc\nd\ne\nf\ng\nh" | awk 'NR==3 || NR==5{$0=$0"\ntest"}1;'

com perl :

$ echo -e "a\nb\nc\nd\ne\nf\ng\nh" | perl -pe '$_ .="test\n" if $. == 3 || $. == 5'
    
por 28.02.2014 / 18:13
3

Como o @HaukeLaging já disse, esse comando faz o que você quer:

sed -e'3a test' -e'5a test'

Agora, isso pode se tornar um pouco trabalhoso se você quiser corresponder, por exemplo, 20 linhas.

Nestes casos, supondo que o seu shell suporta expansão de chaves , você pode usar este comando:

sed -e{3,5}'a test'

(Observe que as chaves e a vírgula devem permanecer sem aspas).

Como resultado, o shell passará os argumentos para -e3a test e -e5a test para sed, que é exatamente o que o primeiro comando faz.

    
por 28.02.2014 / 22:55

Tags