Ich möchte einen Text im Tabellenformat ausgeben. Ich habe versucht, die Elemente eines Arrays mit '\ t' wiederzugeben, aber es war falsch ausgerichtet.
Mein Code
for((i=0;i<array_size;i++));
do
echo stringarray[$i] $'\t' numberarray[$i] $'\t' anotherfieldarray[$i]
done;
Meine Ausgabe
a very long string.......... 112232432 anotherfield
a smaller string 123124343 anotherfield
Gewünschte Ausgabe
a very long string.......... 112232432 anotherfield
a smaller string 123124343 anotherfield
%-10s
Wir erzeugen linksbündige Zeichenfolgen mit einer Länge von 10Verwenden Sie den Spaltenbefehl:
column -t -s' ' filename
quelle
%s
Der Formatbezeichner verwendet Leerzeichen als Trennzeichen. In diesem Fall funktioniert keine der Antworten hier. Ich bin erstaunt, dass Sie wiederholt über die gewünschte Ausgabe sprechen, wenn das Parsen (mit einem beliebigen Werkzeug) vom Trennzeichen der Eingabe abhängt.cat /etc/fstab | sed -r 's/\s+/ /g' | column -t -s' '
function printTable() { local -r delimiter="${1}" local -r data="$(removeEmptyLines "${2}")" if [[ "${delimiter}" != '' && "$(isEmptyString "${data}")" = 'false' ]] then local -r numberOfLines="$(wc -l <<< "${data}")" if [[ "${numberOfLines}" -gt '0' ]] then local table='' local i=1 for ((i = 1; i <= "${numberOfLines}"; i = i + 1)) do local line='' line="$(sed "${i}q;d" <<< "${data}")" local numberOfColumns='0' numberOfColumns="$(awk -F "${delimiter}" '{print NF}' <<< "${line}")" # Add Line Delimiter if [[ "${i}" -eq '1' ]] then table="${table}$(printf '%s#+' "$(repeatString '#+' "${numberOfColumns}")")" fi # Add Header Or Body table="${table}\n" local j=1 for ((j = 1; j <= "${numberOfColumns}"; j = j + 1)) do table="${table}$(printf '#| %s' "$(cut -d "${delimiter}" -f "${j}" <<< "${line}")")" done table="${table}#|\n" # Add Line Delimiter if [[ "${i}" -eq '1' ]] || [[ "${numberOfLines}" -gt '1' && "${i}" -eq "${numberOfLines}" ]] then table="${table}$(printf '%s#+' "$(repeatString '#+' "${numberOfColumns}")")" fi done if [[ "$(isEmptyString "${table}")" = 'false' ]] then echo -e "${table}" | column -s '#' -t | awk '/^\+/{gsub(" ", "-", $0)}1' fi fi fi } function removeEmptyLines() { local -r content="${1}" echo -e "${content}" | sed '/^\s*$/d' } function repeatString() { local -r string="${1}" local -r numberToRepeat="${2}" if [[ "${string}" != '' && "${numberToRepeat}" =~ ^[1-9][0-9]*$ ]] then local -r result="$(printf "%${numberToRepeat}s")" echo -e "${result// /${string}}" fi } function isEmptyString() { local -r string="${1}" if [[ "$(trimString "${string}")" = '' ]] then echo 'true' && return 0 fi echo 'false' && return 1 } function trimString() { local -r string="${1}" sed 's,^[[:blank:]]*,,' <<< "${string}" | sed 's,[[:blank:]]*$,,' }
MUSTER LÄUFT
$ cat data-1.txt HEADER 1,HEADER 2,HEADER 3 $ printTable ',' "$(cat data-1.txt)" +-----------+-----------+-----------+ | HEADER 1 | HEADER 2 | HEADER 3 | +-----------+-----------+-----------+ $ cat data-2.txt HEADER 1,HEADER 2,HEADER 3 data 1,data 2,data 3 $ printTable ',' "$(cat data-2.txt)" +-----------+-----------+-----------+ | HEADER 1 | HEADER 2 | HEADER 3 | +-----------+-----------+-----------+ | data 1 | data 2 | data 3 | +-----------+-----------+-----------+ $ cat data-3.txt HEADER 1,HEADER 2,HEADER 3 data 1,data 2,data 3 data 4,data 5,data 6 $ printTable ',' "$(cat data-3.txt)" +-----------+-----------+-----------+ | HEADER 1 | HEADER 2 | HEADER 3 | +-----------+-----------+-----------+ | data 1 | data 2 | data 3 | | data 4 | data 5 | data 6 | +-----------+-----------+-----------+ $ cat data-4.txt HEADER data $ printTable ',' "$(cat data-4.txt)" +---------+ | HEADER | +---------+ | data | +---------+ $ cat data-5.txt HEADER data 1 data 2 $ printTable ',' "$(cat data-5.txt)" +---------+ | HEADER | +---------+ | data 1 | | data 2 | +---------+
REF LIB unter: https://github.com/gdbtek/linux-cookbooks/blob/master/libraries/util.bash
quelle
-e
Parameter in den Echo-Befehlen entfernen , damit die Striche korrekt gedruckt werden.Um genau die gleiche Ausgabe zu erhalten, die Sie benötigen, müssen Sie die Datei folgendermaßen formatieren:
Und dann mit:
$ column -t -s $'\t' FILE a very long string.......... 112232432 anotherfield a smaller string 123124343 anotherfield
quelle
$
in$'\t'
gerade?Es ist einfacher als Sie sich fragen.
Wenn Sie auch mit einer durch Semikolon getrennten Datei und einem Header arbeiten:
$ (head -n1 file.csv && sort file.csv | grep -v <header>) | column -s";" -t
Wenn Sie mit einem Array arbeiten (Tabulator als Trennzeichen verwenden):
for((i=0;i<array_size;i++)); do echo stringarray[$i] $'\t' numberarray[$i] $'\t' anotherfieldarray[$i] >> tmp_file.csv done; cat file.csv | column -t
quelle
awk
Lösung, die sich mit stdin befasstDa
column
es sich nicht um POSIX handelt, ist dies möglicherweise:mycolumn() ( file="${1:--}" if [ "$file" = - ]; then file="$(mktemp)" cat > "${file}" fi awk ' FNR == 1 { if (NR == FNR) next } NR == FNR { for (i = 1; i <= NF; i++) { l = length($i) if (w[i] < l) w[i] = l } next } { for (i = 1; i <= NF; i++) printf "%*s", w[i] + (i > 1 ? 1 : 0), $i print "" } ' "$file" "$file" if [ "$1" = - ]; then rm "$file" fi )
Prüfung:
printf '12 1234 1 12345678 1 123 1234 123456 123456 ' > file
Testbefehle:
Ausgabe für alle:
Siehe auch:
quelle
if [ "$file" = - ]; then
am Ende sollte seinif [ "$1" = - ]; then
. Mit dem aktuellen Code bereinigen Sie niemals Ihre temporären Dateien.Ich bin mir nicht sicher, wo Sie dies ausgeführt haben, aber der von Ihnen veröffentlichte Code würde nicht die von Ihnen angegebene Ausgabe erzeugen, zumindest nicht in der Bash, mit der ich vertraut bin.
Versuchen Sie stattdessen Folgendes:
stringarray=('test' 'some thing' 'very long long long string' 'blah') numberarray=(1 22 7777 8888888888) anotherfieldarray=('other' 'mixed' 456 'data') array_size=4 for((i=0;i<array_size;i++)) do echo ${stringarray[$i]} $'\x1d' ${numberarray[$i]} $'\x1d' ${anotherfieldarray[$i]} done | column -t -s$'\x1d'
Beachten Sie, dass ich das Gruppentrennzeichen (1d) anstelle der Registerkarte verwende, da diese möglicherweise Arrays enthalten, wenn Sie diese Arrays aus einer Datei abrufen.
quelle
Nur für den Fall, dass jemand das in PHP machen möchte, habe ich einen Kern auf Github gepostet
https://gist.github.com/redestructa/2a7691e7f3ae69ec5161220c99e2d1b3
Rufen Sie einfach an:
$output = $tablePrinter->printLinesIntoArray($items, ['title', 'chilProp2']);
Möglicherweise müssen Sie den Code anpassen, wenn Sie eine PHP-Version verwenden, die älter als 7.2 ist
Rufen Sie danach je nach Umgebung echo oder writeLine auf.
quelle
Der folgende Code wurde getestet und macht genau das, was in der ursprünglichen Frage verlangt wird.
Parameter:% 30s Spalte mit 30 Zeichen und Text rechtsbündig. % 10d Ganzzahlnotation,% 10s funktioniert auch. Klarstellung in Codekommentaren hinzugefügt.
stringarray[0]="a very long string.........." # 28Char (max length for this column) numberarray[0]=1122324333 # 10digits (max length for this column) anotherfield[0]="anotherfield" # 12Char (max length for this column) stringarray[1]="a smaller string....." numberarray[1]=123124343 anotherfield[1]="anotherfield" printf "%30s %10d %13s" "${stringarray[0]}" ${numberarray[0]} "${anotherfield[0]}" printf "\n" printf "%30s %10d %13s" "${stringarray[1]}" ${numberarray[1]} "${anotherfield[1]}" # a var string with spaces has to be quoted printf "\n Next line will fail \n" printf "%30s %10d %13s" ${stringarray[0]} ${numberarray[0]} "${anotherfield[0]}" a very long string.......... 1122324333 anotherfield a smaller string..... 123124343 anotherfield
quelle