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 2
y 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)
pr
yexpand
...columns
evita este problema.➀ unicode may render oddly
but the column count is ok
definitivamente hace que no se aplican awc-paste-pr
ywc-paste-pr
Ellos muestra diferencias en el recuento de columnas.pr
del multibyte caracteres en el entorno local actual (generalmente UTF8).Respuestas:
Solo necesita el
column
comando y dígale que use pestañas para separar columnasPara abordar la controversia de la "celda vacía", solo necesitamos la
-n
opción decolumn
:La página de manual de mi columna indica que
-n
es 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' -t
ignora 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
pr
comando dandy :El "-e24" es "expandir tabulaciones a 24 espacios". Afortunadamente,
paste
coloca un carácter de tabulación entre columnas, por lo quepr
puede expandirlo. Elegí 24 contando los caracteres en "recursivamente enumerable" y agregando 2.fuente
expand
comando directamentepaste file1 file2 | expand -t 24
:?sed
por lo que hay un proceso que no se ejecuta. Utilizapr
cuá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 usahtml
para 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í,
column
es 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 ...columns
es 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
wc
para obtener el ancho de la columna, ysed
para el pad derecho con un carácter visible.
(solo para este ejemplo) ... y luegopaste
para unir las dos columnas con un carácter Tab ...Si desea rellenar la columna derecha:
fuente
Ya casi estás ahí.
paste
coloca 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 -L
muestra la longitud de la línea más larga. En otros sistemas, haga un primer pase con awk. El+1
es 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 laprintf
instrucció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,
sed
ycolumn
parecen variar en la implementación entre sabores y versiones de Unix / Linux, especialmente BSD (y Mac OS X) frente a GNU / Linux.fuente
od -c
y no veo ningún byte nulo. Esto está en centos y ubuntu.\0
no funcionaba como unnull
in sed, pero lo\x0
hizo. Sin embargo, entonces la columna dio unline too long
error. 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
awk
scripts de este tipo, lo primero que se lee arriba esfile1
guardar todos los datos en lasave
matriz y calcular simultáneamente la longitud máxima de la línea. Luego leefile2
e imprime losfile1
datos guardados ( ) junto con losfile2
datos actuales ( ). Finalmente, sifile1
es 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
printf
formato:"%-nns"
imprime una cadena justificada a la izquierda en un campo denn
caracteres de ancho."%-*s", nn
hace lo mismo:*
le dice que tome el ancho del campo del siguiente parámetro.maxlength+2
nn
+2
El 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_length
en una matriz.max_FNR
en una matriz.save
en una matriz bidimensional.END
bloque.fuente
paste
es la mejor solución; específicamente, Glenn Jackmanpaste file1 file2 | column -s $'\t' -t
. Pero pensé que sería divertido intentar mejorar elawk
enfoque.