Sed comando para imprimir cada primeira e décima quarta linha de um arquivo a cada 46 linhas [duplicado]

4

Portanto, analise um arquivo de texto e imprima a linha 1 e a linha 14 e, em seguida, não faça nada com as linhas 15-46 e imprima a linha 47 e a linha 60, etc. até o final do arquivo. Então, basicamente, a cada 46 linhas, imprima a 1ª e a 14ª linha repetidamente para cada 46 linhas até EOF

    
por Nicholas Tree 15.01.2018 / 16:59

3 respostas

12

Usando a extensão do intervalo de endereços do primeiro ~ passo do GNU sed:

sed -n '1~46p; 14~46p;' file
    
por 15.01.2018 / 17:04
11

Como você tem awk em suas tags, fornecerei uma solução com awk :

awk '(NR%46==1||NR%46==14){print}' file
    
por 15.01.2018 / 17:02
5

Nenhum trabalho para POSIX sed :

sed 'H;1h;$!d;x;y/\n#/#\n/;s/\(#[^#]*\)\{12\}#\([^#]*\)\([^#]*#\)\{33\}/###/g;s/\(.*\)##.*//;s/##/#/g;y/\n#/#\n/'

Embora eu considere absurdo usar o POSIX sed para essa tarefa quando outras ferramentas são mais adequadas, adicionarei uma explicação, porque há elementos úteis aqui que você pode precisar em tarefas reais:

  • H;1h;$!d;x é um padrão para coletar todo o arquivo no espaço padrão, o que geralmente é útil (com o GNU sed , você pode substituí-lo usando a opção -z ). Você pode descobrir como isso funciona.
  • y/\n#/#\n/ troca as novas linhas com outro char (neste caso, # ). Faça isso como uma solução alternativa antes e depois do processamento, se precisar de expressões como "todos os caracteres, exceto a nova linha". Novamente, você não precisa disso com o GNU sed , já que [^\n] é permitido lá.
  • Esse padrão estranho no comando s corresponde a 12 + 1 + 33 = 46 # (anteriormente, newlines) e 45 [^#]* , que são o conteúdo da linha. A cada primeira linha é intocada, 12 são removidos, 1 preservados como e 33 removidos. Isso é feito globalmente. O material ## é feito para remover as linhas finais.
por 15.01.2018 / 17:44

Tags