2011-06-24 14 views
45

Mam funkcję, która generuje wiele wierszy informacji, które chcę sformatować w kolumnach. Problem polega na tym, że szerokość jakiejś konkretnej "komórki" (jeśli mogę używać tego terminu) danych jest zmienna, więc podłączenie jej do czegoś takiego jak awk nie daje mi tego, czego chcę.W jaki sposób sformatować dane wyjściowe polecenia bash w czystych kolumnach

Funkcja „Keys” (nie, że jest to ważne) i próbuję coś takiego:

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

ale wyjście (fragment o tym, że jest), wygląda następująco:

"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 

Jak zmusić rzeczy do pozostania w schludnych kolumnach? Czy jest to możliwe w awk, czy też muszę użyć czegoś innego?

Odpowiedz

67

column(1) jest twoim przyjacielem.

$ 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

miło i szybko i użytecznie, ale wersja awk pozwala mi łatwiej ją podkręcać rozwiązać inny problem: podział na coś innego niż spacje. Próbowałem z tym: 'IFS =" ""; klucze | kolumna -t', ale kolumna nie wydaje się respektować wartości $ IFS. – iconoclast

+5

Oczywiście, że nie. Podobnie jak na stronie man, użyj '-s'. –

+1

@Bandon: 'IFS' jest wewnętrznym separatorem pól dla' powłoki', nie dla programów uruchamianych przez powłokę, chociaż * mogą * wykorzystywać te same wartości. –

40

Znaleziono to, wyszukując "sformatowane kolumny wyjściowe systemu Linux".

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

do swoich potrzeb, jak to jest:

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

Nie pokazałem tego na przykładowym wyjściu, ale w niektórych miejscach mam spacje, których ja * nie chcę * dzielić, więc z tą drobną zmianą do fragmentu kodu awk mam rozwiązał problem: klucze | awk 'BEGIN {FS = "\" "}; {printf"% -20s% -40s \ n ", 1 $, 2 $, 3 $}' – iconoclast

3

Podczas awk „s printf może być używany, można zajrzeć do pr lub (w systemach BSDish) rs do formatowania.

3

Ponieważ w systemie AIX nie ma polecenia "kolumna", poniżej został utworzony uproszczony skrypt. Byłoby jeszcze krócej bez doc & wejście zmiany ... :)

#!/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

Spróbuj

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

lub nawet

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

jeśli wejście nie jest zbyt duża.

1

Jeśli dane wyjściowe są rozdzielane tabulatorami, szybkim rozwiązaniem byłoby użycie polecenia tabs w celu dostosowania rozmiaru kart.

tabs 20 
keys | awk '{ print $1"\t\t" $2 }' 
Powiązane problemy