
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