Eu tenho mais de 1000 linhas em um arquivo. O arquivo inicia da seguinte forma (números de linha adicionados):
Station Name
Station Code
A N DEV NAGAR
ACND
ABHAIPUR
AHA
ABOHAR
ABS
ABU ROAD
ABR
Eu preciso converter isso em um arquivo, com entradas separadas por vírgula, juntando-se a cada duas linhas. Os dados finais devem ter a aparência de
Station Name,Station Code
A N DEV NAGAR,ACND
ABHAIPUR,AHA
ABOHAR,ABS
ABU ROAD,ABR
...
O que eu estava tentando era - tentando escrever um script de shell e depois echo
com vírgula no meio. Mas eu acho que uma linha simples eficaz mais simples faria o trabalho aqui pode estar em sed
/ awk
.
Alguma ideia?
Respostas:
Basta usar
cat
(se você gosta de gatos ;-)) epaste
:Explicação:
paste
lê de vários arquivos e cola as linhas correspondentes (linha 1 do primeiro arquivo com linha 1 do segundo arquivo etc):Em vez de um nome de arquivo, podemos usar
-
(traço).paste
pega a primeira linha do arquivo1 (que é stdin). Então, ele deseja ler a primeira linha do arquivo2 (que também é stdin). No entanto, uma vez que a primeira linha do stdin já foi lida e processada, o que agora espera no fluxo de entrada é a segunda linha do stdin, quepaste
cola felizmente na primeira. A-d
opção define o delimitador para ser uma vírgula e não uma guia.Como alternativa, faça
PS Sim, pode-se simplificar o acima para
ou
qual tem a vantagem de não usar
cat
.No entanto, eu não usei esse idioma de propósito , por razões de clareza - é menos detalhado e eu gosto
cat
(GATOS SÃO AGRADÁVEIS). Então, por favor, não edite.Como alternativa, se você preferir colar a gatos (colar é o comando para concatenar arquivos horizontalmente, enquanto gato os concatena verticalmente), você pode usar:
fonte
paste
comando funciona perfeitamente, você pode dar um pouco mais de explicação sobre isso? Os hífens ???cat
argumento. Nãosed "N;s/\n/,/" file.in > file.out
funciona?Caso alguém que esteja aterrissando aqui esteja procurando combinar todas as linhas em um forro CSV único, tente
fonte
Usando sed, junte-se a (N) a cada 2 linhas e substitua a nova linha (\ n) por ",".
fonte
Observe também que, como estamos apenas substituindo um caractere por outro (todas as outras novas linhas por vírgula), podemos trabalhar no arquivo de entrada em vigor:
(mas cuidado, pode não funcionar em sistemas não Unix que possuem terminadores CRLF (como os da Microsoft) que alguns POSIX emulados
paste
podem tratar de maneira não-Unix)fonte
1
está fazendo aqui1<>
? isso é um erro de digitação?Aqui está uma linha (embora potencialmente milhões de comandos executados) usando o Bash puro:
Eu uso um subshell (a parêntese) para não precisar armazenar e restaurar
IFS
. Qual deles deve ser feito para não atrapalhar o ambiente dos usuários, caso a fonte seja originada. A alternativa seria passar esse novo IFS apenas pararead
comoIFS= read -r name
,IFS= read -r code
.O fato de todos os comandos do loop serem construídos no shell torna seu desempenho aceitável e é ainda mais rápido que as outras soluções para arquivos pequenos. Mas muitas pessoas consideram isso uma prática ruim e é preciso ter cuidado ao generalizá-la para qualquer outra coisa.
fonte
while IFS='\n' read -r name; do IFS='\n' read -r code ... done < file.in
, que é um idioma que frequentemente vejo nos scripts de shell. A-r
sinalização pararead
significa "interpretar o caractere '\' seguido pelo caractere 'n' no fluxo stdin como dois caracteres, e não como uma nova linha". Indiscutivelmente, pode ser mais estético criar o subshell do que repetirIFS='\n'
.-r
Melhorou a solução tecnicamente. Ótimo! Não sou fã da ideia de passarIFS
duas vezes alterado . Se eu tivesse usado uma leitura, super legal, mas não duas vezes. Claro que isso é uma questão de opinião . Usar um subshell é um pouco acima do conhecimento geral do Bash, eu diria, então muitas pessoas terão problemas para entender seu objetivo. Isso é uma coisa ruim.Para o conjunto completo de respostas, uma
awk
solução possível pode ser:fonte
printf
? Raramente falhará quando um nome de estação contiver um especificador de formato. (Veja pastebin.com/wgxFttrJ para um exemplo.) Mas isso é apenas um palpite, o voto negativo não é meu.Hoary castanha velha de um
awk
idiomafonte
awk '{ORS=NR%2?",":"\n"};1'
é mais curto e mais idiomaprint
da intenção e é clara.1
é tão claro para velhasawk
mãos, como eu, mas eu prefiroprint
sed
por um tempo antes de pesquisar, masawk
facilitei a combinação a cada 4 linhas. Me salvou uma viagem para o$EDITOR
!Possível com perl também,
perl -pe 's/^\d+\.\s+//;$.&1?chomp:print","' file
fonte
Por exemplo:
Saída: (nota:
xargs -L number_of_columns
funciona bem com quase qualquer número de colunas, não apenas a cada duas linhas)fonte
Solução POSIX com
pr
:http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pr.html
fonte