paste -sd '::\n' file
Ou:
awk '{ORS=NR%3?":":"\n";print}' < file
(note a diferença se o número de registros na entrada não for um múltiplo de 3).
Digamos que eu tenha um arquivo de texto neste formato
field1a
field2a
field3a
field1b
field2b
field3b
Eu quero club 3 (ou no caso geral N) linhas consecutivas, como eu faço isso com sed
ou outro utilitário de linha de comando no bash shell?
saída esperada
field1a:field2a:field3a
field1b:field2b:field3b
paste -sd '::\n' file
Ou:
awk '{ORS=NR%3?":":"\n";print}' < file
(note a diferença se o número de registros na entrada não for um múltiplo de 3).
paste
: paste -d: - - - <file
Mesclar um arquivo colando os dados em três colunas ( - - -
) usando um separador de dois-pontos:
perl -pe 'if($.%3){s/\n/:/;}' file
com a opção -p
faz impressão padrão. Tudo o que fazemos aqui é, se o número da linha for de 3 ( %3
), substitua o caractere de nova linha ( \n
) por dois pontos ( :
).
xargs
e awk
: xargs -L 3 < file | awk '$1=$1' OFS=:
O argumento -L
em xargs
informa quantas linhas ingressar. E awk
coloca o separador de campos de saída (OFS) de Space (por padrão) para separador de dois pontos ( :
).
awk
: awk 'NR%3{printf "%s:",$0;next}{print;}' file
Imprima o módulo de 3 linhas usando printf (sem nova linha) com dois pontos, e faça uma impressão normal para a próxima linha usando print (o que coloca a nova linha por padrão).
Para formatação de saída, você pode usar printf
IFS='
' # split on sequences of newline characters
set -f # disable globbing
printf "%s:%s:%s\n" $(cat file)
(note que ele pula linhas vazias).
Ou sed
(se você quiser)
sed '$!N;$!N;s/\n/:/g' file
com sed
:
sed '$!N;$!N;y/\n/:/'
Embora eu ache que é menos geral do que N linhas do que deveria ser. Se o número de linhas que você deseja sempre estará no final do campo, então:
sed '$q;N;/1.$/!s/\(..*\)\(\n\)/:/;//P;D
' <<\INPUT
field1a
field1b
field2b
field1c
INPUT
field1a
field1b:field2b
field1c
... que empilha linhas após uma que termina com 1
e depois com qualquer caractere até encontrar outra também terminando com 1
e outra coisa.
Funcionaria para qualquer número de campos, mas você pode querer fazer ...
sed '.../[^0-9]1.$/!...'
... se você entrar em vários dígitos.
Se eu tiver apenas algumas centenas ou menos linhas, ou se o número de campos por grupo variar, então o vi funcionará muito bem para mim.
No vi, se eu quiser juntar as duas linhas atuais e seguintes (3 linhas de texto ao todo), então ...
3J
Neste ponto, meu cursor está na linha concatenada, então desço para o próximo ...
j
Eu faço a mesma modificação em relação à linha atual usando o ponto ...
.
E mais uma vez ...
j
.
Oops! Esse último grupo tinha 4 linhas, não 3. Eu desfiz a última modificação ...
u
e faça de novo, certo agora ...
4J
Próximo! ...
j
... e assim por diante.
Note que, se você pretende fazer isso para o seu carregamento de banco de dados de 360 milhões de campos, ou se seus campos consecutivos forem geralmente 3, com alguns grupos de 4 e talvez um grupo raro de 5 ou 6, então você provavelmente quer suportar a sintaxe arcana de sair do circuito, condicionando seus dados por etapas e talvez escrevendo um programa para testá-lo e alertá-lo sobre erros.
Mas se é um trabalho pequeno e único, eu suporto apenas alguns minutos de tédio e uso vi.
Tags text-processing