CSVテーブルを転置するスクリプトを作成しようとしています。いくつかのファイルがあります。
head1;head2;head3
field11;field12;field13
field21;field22;field23
(ちょっと待ってください。)私は欲しい
head1;field11;field21
head2;field12;field22
head3;field13;field23
私はこれを行う方法さえ知らない。スクリプトの作成を要求するものではありません。標準シェルでスクリプトを作成する方法についてのアイデアが必要です。 (残念ながら、bashismまたはGNU拡張は使用できません。POSIXのみ使用できます。)
PSは実際に行うことができますが、醜くて非効率的です。私はもっと美しい方法があると信じています。
答え1
データ転置
head1;head2;head3
field11;field12;field13
field21;field22;field23
field31;field32;field33
これはGNUを使用して行うことができますdatamash
。
$ datamash -t ';' transpose <file
head1;field11;field21;field31
head2;field12;field22;field32
head3;field13;field23;field33
答え2
適応が速いです。バッシュソリューション到着この同様の質問特定の区切り記号(セミコロン)の場合:
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
答え3
データはセミコロンで区切られます(CSVではありません)。したがって、次のコードを試すことができます。
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
答え4
flds=3; for((i=1;i<=flds;i++));do
printf '%s' "$(cut -d';' -f$i file)" |tr '\n' ';';echo
done