Tengo más de 1000 líneas en un archivo. El archivo comienza de la siguiente manera (se agregaron números de línea):
Station Name
Station Code
A N DEV NAGAR
ACND
ABHAIPUR
AHA
ABOHAR
ABS
ABU ROAD
ABR
Necesito convertir esto en un archivo, con entradas separadas por comas uniendo cada dos líneas. Los datos finales deberían verse como
Station Name,Station Code
A N DEV NAGAR,ACND
ABHAIPUR,AHA
ABOHAR,ABS
ABU ROAD,ABR
...
Lo que estaba intentando era: tratar de escribir un script de shell y luego echocon una coma en el medio. Pero supongo que una línea más simple y efectiva haría el trabajo aquí puede estar en sed/ awk.
¿Algunas ideas?

Respuestas:
Simplemente use
cat(si le gustan los gatos ;-)) ypaste:Explicación:
pastelee de varios archivos y pega las líneas correspondientes (línea 1 del primer archivo con la línea 1 del segundo archivo, etc.):En lugar de un nombre de archivo, podemos usar
-(guión).pastetoma la primera línea del archivo1 (que es stdin). Luego, quiere leer la primera línea del archivo2 (que también es estándar). Sin embargo, dado que la primera línea de stdin ya se leyó y procesó, lo que ahora espera en la secuencia de entrada es la segunda línea de stdin, quepastefelizmente se pega a la primera. La-dopción establece que el delimitador sea una coma en lugar de una pestaña.Alternativamente, hacer
PD Sí, uno puede simplificar lo anterior a
o
que tiene la ventaja de no usar
cat.Sin embargo, no utilicé este idioma a propósito , por razones de claridad, es menos detallado y me gusta
cat(LOS GATOS SON AGRADABLES). Así que por favor no edites.Alternativamente, si prefiere pegar a gatos (pegar es el comando para concatenar archivos horizontalmente, mientras que gato los concatena verticalmente), puede usar:
fuente
pastecomando funciona perfectamente, ¿puede darnos un poco más de explicación? Los guiones ???catargumento. Nosed "N;s/\n/,/" file.in > file.outfuncionaEn caso de que alguien que aterriza aquí esté buscando combinar todas las líneas en un revestimiento CSV, intente
fuente
Usando sed, une (N) cada 2 líneas y reemplaza la nueva línea (\ n) con ",".
fuente
También tenga en cuenta que debido a que simplemente estamos reemplazando un carácter con otro (cada línea nueva con una coma), podemos trabajar en el archivo de entrada en su lugar:
(pero tenga en cuenta que podría no funcionar en sistemas que no sean Unix que tengan terminadores CRLF (como los de Microsoft) que algunos POSIX emulados
pastepodrían tratar de una manera que no sea Unix)fuente
1aquí1<>? ¿Es eso un error tipográfico?Aquí hay una línea (aunque potencialmente millones de comandos-run-er) usando Bash puro:
Utilizo una subshell (la parántesis) para no tener que almacenar y restaurar
IFS. De lo contrario, qué debería hacer para no estropear el entorno de los usuarios en caso de que se obtenga la fuente. La alternativa sería pasar que los nuevos IFS sólo parareadque enIFS= read -r name,IFS= read -r code.El hecho de que todos los comandos del bucle estén integrados en el shell hace que su rendimiento sea aceptable y es incluso más rápido que las otras soluciones para archivos pequeños. Pero muchas personas lo considerarían una mala práctica y uno debe tener cuidado al generalizarlo a cualquier otra cosa.
fuente
while IFS='\n' read -r name; do IFS='\n' read -r code ... done < file.in, lo cual es un idioma que a menudo veo en los scripts de shell. El-rindicador areadsignifica "interpretar el carácter '\' seguido del carácter 'n' en la secuencia estándar como dos caracteres, en lugar de como una nueva línea". Podría decirse que puede ser más estético crear la subshell como lo hace que repetirlaIFS='\n'.-rMejoraron técnicamente la solución. ¡Excelente! No soy fanático de la idea de pasar un cambioIFSdos veces. Si hubiera usado una lectura, super agradable, pero no dos veces. Por supuesto que es una cuestión de opinión . El uso de una subshell es un poco mayor que el conocimiento general de Bash, diría, por lo que mucha gente tendrá problemas para comprender su propósito. Eso es algo maloPara el conjunto completo de respuestas, una posible
awksolución puede ser:fuente
printf? Fallará en el raro caso cuando el nombre de una estación contiene un especificador de formato. (Consulte pastebin.com/wgxFttrJ para ver un ejemplo). Pero esto es solo una suposición, el voto negativo no es mío.Canoso viejo castaño de un
awkidiomafuente
awk '{ORS=NR%2?",":"\n"};1'es más corto y más idiomáticoprintla intención y es clara.1es tan claro para las personas mayoresawkcomo yo, pero prefieroprintsedpor un tiempo antes de buscar, peroawkhice que combinar cada 4 líneas sea más fácil. Me salvó un viaje a la$EDITOR!Posible con perl también,
perl -pe 's/^\d+\.\s+//;$.&1?chomp:print","' filefuente
Por ejemplo:
Salida: (nota:
xargs -L number_of_columnsfunciona bien con la mayoría de las columnas, no solo cada dos líneas)fuente
Solución POSIX con
pr:http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pr.html
fuente