Outra solução usando awk
e bash
:
paste -d, <(awk -v RS='\n\n' 'NR%2' file) <(awk -v RS='\n\n' '!(NR%2)' file)
Isso leva em conta apenas linhas vazias como separadores, linhas não vazias podem ser qualquer coisa.
Tenha um arquivo como este:
1
2
3
# always a double newline
a
b
c # each subgroup has the same number of rows
9
10
y
z
...
É basicamente column1, seguido por uma nova linha dupla, depois pela coluna dois, por uma nova linha dupla e de volta à coluna1
Não faça suposições sobre a natureza dos valores (eles poderiam ser qualquer coisa), ou o número de "colunas" (poderia ser 2 ou 3, embora conhecido antecipadamente)
Esperando por um resultado como este:
1,a
2,b
3,c
9,y
10,z
...
Qual é a ferramenta certa para o trabalho?
Outra solução usando awk
e bash
:
paste -d, <(awk -v RS='\n\n' 'NR%2' file) <(awk -v RS='\n\n' '!(NR%2)' file)
Isso leva em conta apenas linhas vazias como separadores, linhas não vazias podem ser qualquer coisa.
Uma solução rápida com seu arquivo de entrada de amostra (copio / colo seus dados de entrada em um arquivo local chamado c2.txt). Ele não foi testado sob todas as condições para possíveis falhas, mas você pode tentar ver se o resultado satisfaz você.
$ paste -d"," <(grep -E '[0-9]' c2.txt) <(grep -E '[a-z]' c2.txt)
1,a
2,b
3,c
9,y
10,z
Na verdade, eu uso o mesmo arquivo duas vezes. Um para números um para strings e colar os une.
Que tal usar o awk no modo de parágrafo; dividindo cada registro ímpar em uma matriz indexada e, em seguida, fazendo um loop através dele usando os índices do seguinte registro par:
awk -vRS= -F'\n' '
NR%2 {split($0,a); next} {for (i=1;i<=NF;i++) print a[i],$i}
' OFS=, file
1,a
2,b
3,c
9,y
10,z
O uso de um separador de campo de nova linha torna mais seguro a entrada mais geral, por exemplo dado file2
foo
bar
baz bar
a
b
c
9
10
hello world
z
então
awk -vRS= -F'\n' '
NR%2 {split($0,a); next} {for (i=1;i<=NF;i++) print a[i],$i}
' OFS=, file2
foo,a
bar,b
baz bar,c
9,hello world
10,z
Como o OP solicitou que os valores de entrada possam ser qualquer coisa e apenas o dobro da nova linha pode ser usado como guia em comentários , aqui está uma versão alternativa do script (o original pode ser encontrado no histórico de edição desta resposta), usando o arquivo de entrada do steeldriver para testes:
#!/usr/bin/env python
from __future__ import print_function
import sys
columns = []
counter = 0
def print_columns(cols):
half = len(cols)/2
print("\n".join([ x+","+y for x,y in zip(cols[0:half],cols[half:]) ]))
with open(sys.argv[1]) as fd:
for line in fd:
if line.strip() == '':
counter+=1
continue
if counter >0 and counter%4 == 0:
print_columns(columns)
columns = []
counter = 0
columns.append(line.strip())
print_columns(columns)
Execução de teste:
$ cat input.txt
foo
bar
baz bar
a
b
c
9
10
hello world
z
$ ./columnate_file.py input.txt
foo,a
bar,b
baz bar,c
9,hello world
10,z
Tags text-processing bsd osx