una texto reemplazar recorrer programacion multiplicar manipulacion extraer especiales cortar caracteres cadenas cadena bash echo

texto - ¿Cómo alinear las columnas de tablas en Bash?



recorrer string bash (7)

Me gustaría dar salida a un texto de formato de tabla. Lo que traté de hacer fue repetir los elementos de una matriz con ''/ t'', pero estaba desalineada. 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


Es más fácil de lo que te preguntas.

Si está trabajando con un archivo y un encabezado separados por punto y coma también:

$ (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


No estoy seguro de dónde estaba ejecutando esto, pero el código que publicaste no produciría el resultado que me diste, al menos no en el bash con el que estoy familiarizado.

Pruebe 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 de separador de grupo (1d) intead de pestaña, porque si obtiene estas matrices de un archivo, pueden contener pestañas.


Para tener exactamente el mismo resultado que necesita, debe formatear el archivo de esa manera:

a very long string........../t 112232432/t anotherfield/n a smaller string/t 123124343/t anotherfield/n

Y luego usando:

$ column -t -s $''/t'' FILE a very long string.......... 112232432 anotherfield a smaller string 123124343 anotherfield


Use el comando de columna:

column -t -s'' '' filename


printf es un pequeño programa sorprendente que mucha gente olvida que existe. Es bastante poderoso.

$ for num in 1 10 100 1000 10000 100000 1000000; do printf "%10s %s/n" $num "foobar"; done 1 foobar 10 foobar 100 foobar 1000 foobar 10000 foobar 100000 foobar 1000000 foobar $ for((i=0;i<array_size;i++)); do printf "%10s %10d %10s" stringarray[$i] numberarray[$i] anotherfieldarray[%i] done

Observe que usé %10s para cadenas. %s es la parte importante. Le dice que use una cadena. El 10 en el medio dice cuántas columnas debe ser. %d es para números (dígitos).

man 1 printf para más información.


awk solución que se ocupa de stdin

Como la column 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 [ "$file" = - ]; then rm "$file" fi )

Prueba:

printf ''12 1234 1 12345678 1 123 1234 123456 123456 '' > file

Comandos de prueba:

mycolumn file mycolumn <file mycolumn - <file

Salida para todos:

12 1234 1 12345678 1 123 1234 123456 123456

Ver también:


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:]]*$,,'' }

EJEMPLO DE EJECUCIONES

$ 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