Eu tenho algum arquivo como este:
abc 123
abc 789
bcd 456
acb 135
Gostaria de imprimir a primeira coluna da próxima linha na linha atual.
Saída desejada:
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
Eu prefiro usar awk.
Eu tenho algum arquivo como este:
abc 123
abc 789
bcd 456
acb 135
Gostaria de imprimir a primeira coluna da próxima linha na linha atual.
Saída desejada:
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
Eu prefiro usar awk.
Respostas:
Memorize a linha anterior:
awk 'NR > 1 { print prev, $1 } { prev = $0 } END { print prev }'
Isso processa a entrada da seguinte maneira:
prev
, consulte a próxima etapa) e o primeiro campo da linha atual, separado pelo separador do campo de saída (o caractere de espaço por padrão);prev
variável;awk
Abordagem alternativa :
$ awk 'NR == 1{printf "%s", $0;next}{printf " %s\n%s", $1,$0}' input.txt
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
A maneira como isso funciona é simples: a primeira linha é um caso especial - nós a imprimimos sem nova linha e dizemos ao awk para ir para a próxima linha sem executar outros blocos de código. Depois disso, NR == 1{printf "%s", $0;next}
é ignorado, mas outras partes fazem o trabalho.
Lembre-se de que, até agora, imprimimos uma string formatada sem novos caracteres de linha. Portanto, o que está sendo feito printf " %s\n%s",$1,$0
agora é a primeira palavra impressa (e, como não havia nova linha, ela permanece na mesma linha de saída), a nova linha inserida e a própria linha inteira (mas não termina com o caractere de nova linha) . Assim, a próxima primeira palavra inserida permanecerá na mesma linha. O processo continua até chegarmos ao final do arquivo.
Uma possível melhoria é incluir um END{print ""}
bloco para inserir uma nova linha final. Em certos casos em que o arquivo resultante deve ser processado por outros scripts, pode ser desejável.
Enquanto o usuário solicitou o AWK especificamente, a mesma abordagem com a impressão de seqüências de caracteres formatadas pode ser adotada com outros idiomas, por exemplo, Python. Alternativa Python fornecida para aqueles curiosos sobre como isso pode ser implementado em outros idiomas:
#!/usr/bin/env python
from __future__ import print_function
import sys
old = None
for index,line in enumerate(sys.stdin):
if index == 0:
print(line.strip(),end=" ")
continue
words = line.strip().split()
print(words[0] + "\n" + line.strip(),end=" ")
E uso assim:
$ ./append_first.py < input.txt
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
A mesma idéia sobre a nova linha final se aplica aqui.
Aqui está uma sed
maneira feia apenas por diversão
sed '2,$ s/[^ ]\+/& &/; 2,$ s/ /\n/' file | paste -d ' ' - -
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
2,$
da segunda linha até a últimas/[^ ]\+/& &/
dobrar o primeiro conjunto de caracteres que não são espaços em branco;
separa comandos, como no shells/ /\n/
substitua o primeiro espaço por uma nova linhapaste -d ' ' - -
junte essa bagunça (acrescente a segunda linha à terceira, a quarta linha à terceira, etc)sed
programas para se divertir, então talvez você deve ter um ir para o código-golf ;-)
Na minha opinião, a abordagem mais simples e legível é:
cut
)tail
)paste
)Exemplo: seu arquivo inpult de amostra:
abc 123
abc 789
bcd 456
acb 135
Em seguida, execute o seguinte comando em um terminal
cut -d' ' -f1 in.txt | tail -n +2 | paste -d' ' file -
Resultado:
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
A estrutura por trás dessa solução difere das respostas fornecidas. Não há necessidade de condições, loops ou expressão regular.
sed
sozinho sempaste
:sed -r 'N;s/\n(\w+)/\1&/;P;D' somefile.txt