Me gustaría generar un texto en formato de tabla. Lo que intenté hacer fue hacer eco de los elementos de una matriz con '\ t', pero estaba desalineado.
Mi código
for((i=0;i<array_size;i++));
do
echo stringarray[$i] $'\t' numberarray[$i] $'\t' anotherfieldarray[$i]
done;
Mi salida
a very long string.......... 112232432 anotherfield
a smaller string 123124343 anotherfield
Salida deseada
a very long string.......... 112232432 anotherfield
a smaller string 123124343 anotherfield
%-10s
generará cadenas alineadas a la izquierda de longitud 10Usar comando de columna:
column -t -s' ' filename
fuente
%s
El especificador de formato toma espacios en blanco como delimitador. En ese caso, ninguna de las respuestas aquí funcionará. Me sorprende que hable repetidamente sobre la salida deseada cuando el análisis (usando cualquier herramienta) depende del delimitador de la entrada.cat /etc/fstab | sed -r 's/\s+/ /g' | column -t -s' '
Para tener exactamente la misma salida que necesita, debe formatear el archivo de esa manera:
Y luego usando:
$ column -t -s $'\t' FILE a very long string.......... 112232432 anotherfield a smaller string 123124343 anotherfield
fuente
$
de$'\t'
hacer?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:]]*$,,' }
EJECUCIONES DE MUESTRA
$ 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 en: https://github.com/gdbtek/linux-cookbooks/blob/master/libraries/util.bash
fuente
-e
parámetro en los comandos de eco para que los guiones se impriman correctamente.Es más fácil de lo que te imaginas.
Si también está trabajando con un archivo y un encabezado separados por punto y coma:
$ (head -n1 file.csv && sort file.csv | grep -v <header>) | column -s";" -t
Si está trabajando con una matriz (usando la pestaña como separador):
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
fuente
awk
solución que se ocupa de stdinDado
column
que no es POSIX, tal vez esto sea: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 )
Prueba:
printf '12 1234 1 12345678 1 123 1234 123456 123456 ' > file
Comandos de prueba:
Salida para todos:
Ver también:
fuente
if [ "$file" = - ]; then
al final debería serif [ "$1" = - ]; then
. Con el código actual, nunca limpia sus archivos temporales.No estoy seguro de dónde estaba ejecutando esto, pero el código que publicó no produciría el resultado que dio, al menos no en el bash con el que estoy familiarizado.
Prueba esto en su lugar:
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'
Tenga en cuenta que estoy usando el carácter separador de grupo (1d) en lugar de la pestaña, porque si obtiene estas matrices de un archivo, es posible que contengan pestañas.
fuente
En caso de que alguien quiera hacer eso en PHP, publiqué una esencia en Github
https://gist.github.com/redestructa/2a7691e7f3ae69ec5161220c99e2d1b3
simplemente llame:
$output = $tablePrinter->printLinesIntoArray($items, ['title', 'chilProp2']);
es posible que deba adaptar el código si está utilizando una versión de php anterior a la 7.2
después de esa llamada echo o writeLine dependiendo de su entorno.
fuente
El siguiente código ha sido probado y hace exactamente lo que se solicita en la pregunta original.
Parámetros:% 30s Columna de 30 caracteres y texto alineado a la derecha. Notación entera% 10d,% 10s también funcionará. Se agregó una aclaración en los comentarios del código.
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
fuente