Tengo dos archivos de texto. El primero tiene contenido:
Languages
Recursively enumerable
Regular
mientras que el segundo tiene contenido:
Minimal automaton
Turing machine
Finite
Quiero combinarlos en un archivo en columna. Así que lo intenté paste 1 2y su salida es:
Languages Minimal automaton
Recursively enumerable Turing machine
Regular Finite
Sin embargo, me gustaría alinear bien las columnas, como
Languages Minimal automaton
Recursively enumerable Turing machine
Regular Finite
Me preguntaba si sería posible lograr eso sin un manejo manual.
Adicional:
Aquí hay otro ejemplo, donde el método de Bruce casi lo clava, excepto una ligera desalineación sobre la cual me pregunto por qué.
$ cat 1
Chomsky hierarchy
Type-0
—
$ cat 2
Grammars
Unrestricted
$ paste 1 2 | pr -t -e20
Chomsky hierarchy Grammars
Type-0 Unrestricted
— (no common name)

pryexpand...columnsevita este problema.➀ unicode may render oddlybut the column count is okdefinitivamente hace que no se aplican awc-paste-prywc-paste-prEllos muestra diferencias en el recuento de columnas.prdel multibyte caracteres en el entorno local actual (generalmente UTF8).Respuestas:
Solo necesita el
columncomando y dígale que use pestañas para separar columnasPara abordar la controversia de la "celda vacía", solo necesitamos la
-nopción decolumn:La página de manual de mi columna indica que
-nes una "extensión Debian GNU / Linux". Mi sistema Fedora no presenta el problema de celda vacía: parece derivarse de BSD y la página del manual dice "La versión 2.23 cambió la opción -s para que no sea codiciosa"fuente
column, por supuesto; lo obvio (en retrospectiva) 1 ... Gracias ...column -s $'\t' -tignora las celdas vacías , lo que da como resultado que todas las celdas posteriores a la derecha (en esa línea) se muevan a la izquierda; es decir, como resultado de una línea en blanco en un archivo, o que sea más corta ... :(Estás buscando el práctico
prcomando dandy :El "-e24" es "expandir tabulaciones a 24 espacios". Afortunadamente,
pastecoloca un carácter de tabulación entre columnas, por lo queprpuede expandirlo. Elegí 24 contando los caracteres en "recursivamente enumerable" y agregando 2.fuente
expandcomando directamentepaste file1 file2 | expand -t 24:?sedpor lo que hay un proceso que no se ejecuta. Utilizaprcuál es un comando antiguo, que data de los días de Unix SysV, creo, por lo que podría existir en más instalaciones queexpand. Es solo la vieja escuela, en resumen.Actualización : Aquí hay un script mucho más simple (el que está al final de la pregunta) para la salida tabulada. Simplemente pásale el nombre de archivo como lo harías
paste... Se usahtmlpara hacer el marco, por lo que es modificable. Conserva múltiples espacios, y la alineación de la columna se conserva cuando encuentra caracteres unicode. Sin embargo, la forma en que el editor o el espectador representa el Unicode es otra cuestión completamente ...---
Una sinopsis de las herramientas presentadas en las respuestas (hasta ahora).
Los he mirado de cerca; Esto es lo que he encontrado:
paste# Esta herramienta es común a todas las respuestas presentadas hasta ahora # Puede manejar múltiples archivos; por lo tanto múltiples columnas ... ¡Bien! # Delimita cada columna con una pestaña ... Bien. # Su salida no está tabulada.¡Todas las herramientas a continuación eliminan este delimitador! ... Malo si necesita un delimitador.
column# Elimina el delimitador de tabulación, por lo que la identificación del campo es puramente por columnas que parece manejar bastante bien ... No he visto nada extraño ... # Además de no tener un delimitador único, ¡funciona bien!expand# Solo tiene una configuración de pestaña única, por lo que es impredecible más allá de 2 columnas # La alineación de las columnas no es precisa cuando se maneja unicode, y elimina el delimitador de pestaña, por lo que la identificación del campo es puramente por alineación de columnapr# Solo tiene una configuración de pestaña única, por lo que es impredecible más allá de 2 columnas. # La alineación de las columnas no es precisa cuando se maneja unicode, y elimina el delimitador de Tabulación, por lo que la identificación del campo es puramente por la alineación de la columna.Para mí,
columnes la mejor solución obvia como una línea. Si quieres el delimitador o una tabulación de arte ASCII de tus archivos, sigue leyendo, de lo contrario ...columnses bastante bueno:) ...Aquí hay una secuencia de comandos que toma cualquier cantidad de archivos y crea una presentación tabulada de arte ASCII. los números están equivocados, como es el caso en algunas de las utilidades mencionadas anteriormente.) ... La salida del script, que se muestra a continuación, es de 4 archivos de entrada, llamados F1 F2 F3 F4 ...
Aquí está mi respuesta original (recortada un poco en lugar del guión anterior)
Utilizando
wcpara obtener el ancho de la columna, ysedpara el pad derecho con un carácter visible.(solo para este ejemplo) ... y luegopastepara unir las dos columnas con un carácter Tab ...Si desea rellenar la columna derecha:
fuente
Ya casi estás ahí.
pastecoloca un carácter de tabulación entre cada columna, por lo que todo lo que necesita hacer es expandir las pestañas. (Supongo que sus archivos no contienen pestañas). Es necesario determinar el ancho de la columna izquierda. Con las utilidades GNU (lo suficientemente recientes),wc -Lmuestra la longitud de la línea más larga. En otros sistemas, haga un primer pase con awk. El+1es la cantidad de espacio en blanco que desea entre columnas.Si tiene la utilidad de columna BSD, puede usarla para determinar el ancho de la columna y expandir las pestañas de una vez. (
␉es un carácter de tabulación literal; en bash / ksh / zsh puede usar$'\t'en su lugar, y en cualquier shell que pueda usar"$(printf '\t')").fuente
wc, el comando debe ser:wc -L <left.txt... porque, cuando un nombre de archivo se spedified como una línea de comando arg , su nombre se emite por la salida estándarEsto es de varios pasos, por lo que no es óptimo, pero aquí va.
1) Encuentra la longitud de la línea más larga
file1.txt.Con su ejemplo, la línea más larga es 22.
2) Use awk para rellenar
file1.txt, rellenando cada línea con menos de 22 caracteres hasta 22 con laprintfinstrucción.Nota: Para FS, use una cadena que no exista en
file1.txt.3) Use pegar como lo hizo antes.
Si esto es algo que haces a menudo, esto se puede convertir fácilmente en un script.
fuente
while IFS= read -r line, de lo contrario, el shell alterará los espacios en blanco y las barras invertidas. Pero el shell no es la mejor herramienta para ese trabajo; Las versiones recientes de GNU coreutils hanwc -L(véase la respuesta de Fred), o se puede usar awk:awk 'n<length {n=length} END {print +n}'.No puedo comentar sobre la respuesta de Glenn Jackman, así que agrego esto para abordar el problema de las celdas vacías que Peter.O notó. Agregar un carácter nulo antes de cada pestaña elimina las corridas de delimitadores que se tratan como un salto único y soluciona el problema. (Originalmente usé espacios, pero usar el carácter nulo elimina el espacio adicional entre columnas).
Si el carácter nulo causa problemas por varias razones, intente:
o
Ambas,
sedycolumnparecen variar en la implementación entre sabores y versiones de Unix / Linux, especialmente BSD (y Mac OS X) frente a GNU / Linux.fuente
od -cy no veo ningún byte nulo. Esto está en centos y ubuntu.\0no funcionaba como unnullin sed, pero lo\x0hizo. Sin embargo, entonces la columna dio unline too longerror. Lo más simple parece ser usar un espacio y vivir con el personaje extra.Basándose en la respuesta de bahamat : esto se puede hacer completamente
awk, leyendo los archivos solo una vez y sin crear ningún archivo temporal. Para resolver el problema como se indica, hagaAl igual que con muchos
awkscripts de este tipo, lo primero que se lee arriba esfile1guardar todos los datos en lasavematriz y calcular simultáneamente la longitud máxima de la línea. Luego leefile2e imprime losfile1datos guardados ( ) junto con losfile2datos actuales ( ). Finalmente, sifile1es más largo quefile2(tiene más líneas), imprimimos las últimas líneas defile1(las que no tienen una línea correspondiente en la segunda columna).En cuanto al
printfformato:"%-nns"imprime una cadena justificada a la izquierda en un campo denncaracteres de ancho."%-*s", nnhace lo mismo:*le dice que tome el ancho del campo del siguiente parámetro.maxlength+2nn+2El script anterior funciona solo para dos archivos. Se puede modificar trivialmente para manejar tres archivos, o para manejar cuatro archivos, etc., pero esto sería tedioso y se deja como un ejercicio. Sin embargo, resulta que no es difícil modificarlo para manejar cualquier número de archivos:
Esto es muy similar a mi primer script, excepto
max_lengthen una matriz.max_FNRen una matriz.saveen una matriz bidimensional.ENDbloque.fuente
pastees la mejor solución; específicamente, Glenn Jackmanpaste file1 file2 | column -s $'\t' -t. Pero pensé que sería divertido intentar mejorar elawkenfoque.