Executa operações sed em números de linha dados

7

Eu estou querendo saber se existe uma maneira simples de operar em certas linhas com números de linha pré-atribuídos.

Digamos que eu queira mostrar as linhas 1, 7, 14 e 16 de um arquivo, posso simplesmente fazer

sed -n '1p;7p;14p;16p' input_file

mas isso fica mais complicado quando a operação não está apenas imprimindo, e eu não quero escrever o mesmo comando longo 4 vezes (e sim, eu sei que posso construir este longo comando sed substituindo a mesma variável bash 4 vezes, mas isso não é ideal o suficiente ...), ou seja,

sed -n '1{long_command};7{long_command};14{long_command};16{long_command}' input_file

Existe uma maneira de fazer a operação nessas linhas específicas do meu arquivo? Eu estou esperando algo como,

sed -n '1,7,14,16p'

que certamente não funcionará no formulário atual.

Qualquer ajuda será apreciada. "Não, não é possível." com explicações é também uma resposta que eu aceito.

    
por Weijun Zhou 15.01.2018 / 17:37

3 respostas

11

Você pode usar ramificações:

sed '
  1b1
  7b1
  14b1
  16b1

  # for the rest to be left alone, branch off (or delete them with "d"):
  b

  :1
  long_command'

(observe que você também pode adicionar alguns 20,25b1 intervalos de linha ou /re/b1 para incluir linhas que correspondam a re ).

Ou você pode usar awk :

awk 'NR == 1 || NR == 7 || ... {stuff}'

Ou usando um hash:

awk -v l=1,7,14,16 '
  BEGIN{split(l, a, ","); for (i in a) lines[a[i]]}

  NR in lines {stuff}'

(ou BEGIN{lines[1]lines[7]lines[14]lines[16]} se não houver muitos)

    
por 15.01.2018 / 17:42
3

Basta inverter sua seleção e excluí-la:

sed '2,6d;8,13d;15d;17,$d;long_command'
    
por 15.01.2018 / 17:52
1

Primeira variante:

Você pode usar esse truque:

sed -nf <(printf '%dp\n' 1 7 14 16)

-f script-file - add the contents of script-file to the commands to be executed.

Teste

seq 1 20 | sed -nf <(printf '%dp\n' 1 7 14 16)

Resultado

1
7
14
16

Segunda variante:

No começo, o auxiliar sed é usado para filtrar apenas as linhas necessárias do arquivo, então essas linhas são canalizadas para o principal sed com o comando longo.

sed -n '1p; 7p; 14p; 16p' input.txt | sed 'long command'
    
por 16.01.2018 / 19:44

Tags