複数のファイル(* data.txt)があり、列1の内容に基づいて各ファイルを複数のファイルに分割しようとしています。私はそれらを分割しましたが、$filename
使用する出力ファイルの列1($ 1)を使用して名前を付ける方法がわかりませんprint
。現在、次のコマンドの印刷は$1 ".txt"
次の内容を提供します。代わりに、ENSG00000115232.txt file1_ENSG00000108094.txt, file1_ENSG00000115232.txt は各入力ファイルに対して個別の出力が必要なため、不適切です。私のコマンドは次のとおりです。"$b"
予想される結果を得るには、このコマンドをどこで使用するのかわかりません。
for filename in *_data.txt
do
b=${filename%%_data.txt}
cat $filename | awk 'NR==1 {header = $0; next}!header_printed[$1]++ {print header > $1".txt"}{print > $1".txt"}'
done
ありがとうございます。
答え1
シェル変数をawkプログラムに渡す方法はいくつかあります。
-v
コマンドラインオプションを使用してください。awk -v b=${filename%data.txt} '... {print > (b $1 ".txt")}'
awkプログラムの後に通常のパラメータに値を渡します。
awk '... {print > (b $1 ".txt")}' b=${filename%data.txt}
値を渡してください。環境内部配列を介して
ENVIRON
awkとしてアクセスします。b=${filename%data.txt} awk '... {print > (ENVIRON["b"] $1 ".txt")}'
ただし、「いくつかの」ファイルしかない場合は、シェルループを完全に省略し、すべてのワイルドカードファイルをawkに直接渡すことが合理的かもしれません。ここでは、FILENAME
出力ファイルのプレフィックスを内部変数からエクスポートできます。例:
awk '
FNR==1 {header = $0; b = FILENAME; sub(/data.txt$/,"",b); next}
!header_printed[b $1]++ {print header > (b $1 ".txt")}
{print > (b $1 ".txt")}
' *_data.txt
(サフィックスを使用split
またはsubstr
削除することもできます。シェル拡張に最も近い正規表現を使用しました。)data.txt
sub
${filename%data.txt}