tabla de transposición de script simple

tabla de transposición de script simple

Estoy intentando escribir un script que simplemente transponga una tabla CSV. Tengo algún archivo:

head1;head2;head3
field11;field12;field13
field21;field22;field23

(y así sucesivamente), y quiero

head1;field11;field21
head2;field12;field22
head3;field13;field23

Ni siquiera tengo idea de cómo se puede hacer. No te pido que escribas un script, necesito una idea sobre cómo puedo hacerlo en un shell estándar (desafortunadamente no puedo usar bashism o extensiones GNU, solo POSIX)

PD. En realidad, puedo hacerlo, pero sólo de una manera fea e ineficiente. Creo que hay una manera más hermosa.

Respuesta1

Transponiendo los datos

head1;head2;head3
field11;field12;field13
field21;field22;field23
field31;field32;field33

se puede hacer con GNU datamash:

$ datamash -t ';' transpose <file
head1;field11;field21;field31
head2;field12;field22;field32
head3;field13;field23;field33

Respuesta2

He aquí una rápida adaptación dela solución bashaesta pregunta SO similarpara los separadores particulares que tienes (punto y coma):

declare -a array=( )                      # we build a 1-D-array

IFS=';' read -a line < "$1"                       # read the headline

COLS=${#line[@]}                          # save number of columns

index=0
while IFS=';' read -a line ; do
    for (( COUNTER=0; COUNTER<${#line[@]}; COUNTER++ )); do
        array[$index]=${line[$COUNTER]}
        ((index++))
    done
done < "$1"

for (( ROW = 0; ROW < COLS; ROW++ )); do
  printf "%s" ${array[$ROW]}
  for (( COUNTER = ROW+COLS; COUNTER < ${#array[@]}; COUNTER += COLS )); do
    printf ";%s" ${array[$COUNTER]}
  done
  printf "\n" 
done

Respuesta3

Sus datos están separados por punto y coma (no CSV). Como tal, puedes probar este código:

awk -F';' '{OFS=";"}{ for (i=1; i<=NF; i++) a[i]= (i in a?a[i] OFS :"") $i; } 
    END{ for (i=1; i<=NF; i++) print a[i] }' input.txt

head1;field11;field21;field31
head2;field12;field22;field32
head3;field13;field23;field33

Respuesta4

flds=3; for((i=1;i<=flds;i++));do
  printf '%s' "$(cut -d';' -f$i file)" |tr '\n' ';';echo
done

información relacionada