1775 個の .txt ファイルがあり、各 .txt ファイルには 3023 行があります。
RIBBY_g_5ZCV995_BI_SNP_D04_38774.CEL
FQC-10090295 0.007813
FQC-10119363 0.023438
FQC-10132112 0.093750
...
UNTIL_g_3ECO791_BI_SNP_H10_36454.CEL
FQC-10090295 0.187500
FQC-10119363 0.023438
FQC-10132112 0.039063
...
転置されたtxtファイルを表す行列を次のように作成するにはどうすればよいですか?
FQC-10090295 FQC-10119363 FQC-10132112 ...
RIBBY_g_5ZCV995_BI_SNP_D04_38774.CEL 0.007813 0.023438 0.093750 ...
UNTIL_g_3ECO791_BI_SNP_H10_36454.CEL 0.187500 0.023438 0.039063 ...
答え1
あなたの質問には指定されていない多くのパラメータが含まれていますが、開始点として次のbash
スクリプトを検討してください。
header=
for f in *.CEL
do
if [ -z "$header" ]
then
l=${#f} # length of filename ...
fmt="%-${l}s" # ... determines width of first column
header="$(printf "$fmt" "")" # first column of first row is blank
for col in $(awk '{print $1}' $f)
do
l=${#col} # width of column
[ $l -lt 8 ] && l=8 # min width of 8
header="$header $(printf "%-${l}s" "$col")" # append column label to header
fmt="$fmt %-$l.6f"
done
printf '%s\n' "$header" # header is first row of output
fi
printf "$fmt\n" "$f" $(awk '{print $2}' $f) # print filename and all column 2 values
done
スクリプトを実行すると、次のようになります。
FQC-10090295 FQC-10119363 FQC-10132112
RIBBY_g_5ZCV995_BI_SNP_D04_38774.CEL 0.007813 0.023438 0.093750
入力ファイルを2番目のファイル名にコピーして再実行しました。
FQC-10090295 FQC-10119363 FQC-10132112
RIBBY_g_5ZCV995_BI_SNP_D04_38774.CEL 0.007813 0.023438 0.093750
RIBBY_g_5ZCV995_BI_SNP_D04_38775.CEL 0.007813 0.023438 0.093750
スクリプトは最初にすべての*.CEL
ファイルを繰り返します。
最初のファイルの場合、スクリプトはheader
すべてのファイル名の長さが同じであるという前提に基づいてヘッダー行を作成します。ヘッダー行を作成すると、スクリプトは列形式データを表示するために使用されるprintf
形式文字列も作成します。fmt
書式文字列の最初のフィールドは、ファイル名を表示するのに十分長い文字列です。
次に、スクリプトは、値ラベルである最初の入力ファイルのすべての「列1」の値を繰り返します。各列に対して、スクリプトは値ラベルの長さ(8以上)を再度取得し、そのラベルをヘッダーに追加します。また、文字列に浮動小数点形式仕様を追加しますfmt
。
スクリプトは、すべての列ラベルを繰り返した後に構成されたタイトル文字列を出力します。
上記のすべてのステップは次のように発生します。最初ファイルのみ。
最初のファイル処理の最後のステップ、ただ最初の後のすべてのファイルを処理する手順は、最初のループ反復中に生成された文字列を使用してprintf
ファイル名と「列2」の値を表示することです。fmt
その後、スクリプトは次の*.CEL
ファイル(利用可能な場合)に進みます。
この方法では、列ラベルがすべてのファイルで同じで、すべての*.CEL
ファイル名の長さが同じであると仮定します。
答え2
次のようなものが必要です。
$ cat tst.awk
BEGIN { OFS="\t" }
FNR==1 {
row = $1
rows[row]
next
}
{
col = $1
cols[col]
vals[row,col] = $2
}
END {
printf "%s", ""
for (col in cols) {
printf "%s%s", OFS, col
}
print ""
for (row in rows) {
printf "%s", row
for (col in cols) {
printf "%s%s", OFS, vals[row,col]
}
print ""
}
}
ただし、お客様の要件を明確にする入力/出力がないため、テストできます(参照私のコメント)、これは検証されていない推測にすぎません。