2011-06-24 18 views
45

Tengo una función que genera muchas filas de información que quiero formatear en columnas. El problema es que el ancho de cualquier "celda" particular (si puedo usar ese término) de datos es variable, por lo que conectarlo a algo como awk no me da lo que quiero.¿Cómo puedo formatear la salida de un comando bash en columnas nítidas?

La función es "claves" (no es que importe) y estoy intentando algo como esto:

$ keys | awk '{ print $1"\t\t" $2 }' 

pero la salida (un fragmento de la misma, que es) es el siguiente:

"option-y"  yank-pop 
"option-z"  execute-last-named-cmd 
"option-|"  vi-goto-column 
"option-~"  _bash_complete-word 
"option-control-?"  backward-kill-word 
"control-_"  undo 
"control-?"  backward-delete-char 

¿Cómo puedo obligar a las cosas a mantenerse en columnas ordenadas? ¿Es esto posible con awk, o necesito usar algo más?

Respuesta

67

column(1) es su amigo.

$ column -t <<< '"option-y"  yank-pop 
> "option-z"  execute-last-named-cmd 
> "option-|"  vi-goto-column 
> "option-~"  _bash_complete-word 
> "option-control-?"  backward-kill-word 
> "control-_"  undo 
> "control-?"  backward-delete-char 
> ' 
"option-y"   yank-pop 
"option-z"   execute-last-named-cmd 
"option-|"   vi-goto-column 
"option-~"   _bash_complete-word 
"option-control-?" backward-kill-word 
"control-_"   undo 
"control-?"   backward-delete-char 
+0

agradable y rápido y útil, pero la versión awk me permite modificarla más fácilmente resolver otro problema: dividir algo que no sean espacios. Intenté con esto: 'IFS = '"'; llaves | column -t' pero la columna no parece respetar el valor de $ IFS. – iconoclast

+5

Por supuesto que no. Al igual que la página del hombre dice, usa '-s'. –

+1

@Brandon: 'IFS' es el separador de campo interno para el' shell', no para los programas que se ejecutan a través del shell, aunque * pueden * utilizar el mismo valor (es). –

40

Se encontró esto al buscar "columnas con formato de salida de Linux".

http://www.unix.com/shell-programming-scripting/117543-formatting-output-columns.html

para sus necesidades, es como:

awk '{ printf "%-20s %-40s\n", $1, $2}' 
+2

yo no mostrar esto en el resultado de ejemplo que di, pero en algunos lugares que tienen espacios que * no * que desee dividir en, por lo que con este pequeño pellizco a su fragmento de awk tengo resuelto el problema: claves | awk 'BEGIN {FS = "\" "}; {printf"% -20s% -40s \ n ", $ 1, $ 2, $ 3}' – iconoclast

3

Mientras awk 's printf se puede utilizar, es posible que desee ver en pr o (en los sistemas BSDish) rs para el formato.

3

Dado que AIX no tiene un comando de "columna", creé el script simplista a continuación. Sería incluso más corto sin el doc edita & de entrada ... :)

#!/usr/bin/perl 
#  column.pl: convert STDIN to multiple columns on STDOUT 
#  Usage: column.pl column-width number-of-columns file... 
# 
$width = shift; 
($width ne '') or die "must give column-width and number-of-columns\n"; 
$columns = shift; 
($columns ne '') or die "must give number-of-columns\n"; 
($x = $width) =~ s/[^0-9]//g; 
($x eq $width) or die "invalid column-width: $width\n"; 
($x = $columns) =~ s/[^0-9]//g; 
($x eq $columns) or die "invalid number-of-columns: $columns\n"; 

$w = $width * -1; $c = $columns; 
while (<>) { 
     chomp; 
     if ($c-- > 1) { 
       printf "%${w}s", $_; 
       next; 
     } 
     $c = $columns; 
     printf "%${w}s\n", $_; 
} 
print "\n"; 
1

Trate

xargs -n2 printf "%-20s%s\n" 

o incluso

xargs printf "%-20s%s\n" 

si la entrada no es muy grande.

1

Si su salida está delimitada por pestañas, una solución rápida sería usar el comando tabs para ajustar el tamaño de sus pestañas.

tabs 20 
keys | awk '{ print $1"\t\t" $2 }' 
Cuestiones relacionadas