私のディレクトリには何千ものファイルがありますが、フィルタリングしたいファイルには次の構文があります。*.imputed.*_info
awkを使用して、データの5番目の列値が0.50を超える各ファイルのレコードをフィルタリングしたいと思います。次の方法を使用できますawk '{if($5 >= .5) {print}}' filename
。
それも動作します。次に、500 個程度のファイル全体を繰り返しながら、この基準を満たす各ファイルのレコードを連結してみました。
以下を試しましたが、構文が正しくありません。
touch snplist.txt
for name in *.imputed.*_info; do
snps="awk '{if($5 >= .5) {print}}' $name"
cat snplist.txt "$snps" > snplist.txt
done
ベストアンサー1
コードは繰り返すたびに出力ファイルを上書きします。あなたも実際に電話をかけていませんawk
。
やりたいことは次のとおりです。
awk '$5 >= 0.5' ./*.imputed.*_info >snplist.txt
これにより、awk
すべてのファイルが一度に呼び出され、シェルの拡張ワイルドカードパターン順序に従って1つずつ繰り返されます。ファイル内の行の5番目の列が0.5以上の場合、その行が出力されます(snplist.txt
)。これは、条件に関連付けられたジョブ(ブロック)がない場合、デフォルトのジョブが{...}
現在の行を出力するためです。
お持ちの場合大きいファイル数(千)が原因で、「パラメータリストが多すぎる」エラーが発生する可能性があります。この場合、以下を繰り返す必要があります。
for filename in ./*.imputed.*_info; do
awk '$5 >= 0.5' "$filename"
done >snplist.txt
結果はawk
変数に保存する必要はありません。ここでは出力されます。サイクル(したがって、ループ内のすべてのコマンド)はにリダイレクトされますsnplist.txt
。
何千ものファイルの場合は、awk
各ファイルを個別に呼び出す必要があるため、非常に遅くなります。
作業を高速化するには、単一の呼び出しでファイルが多すぎる場合は、次の方法をawk
使用することをお勧めします。xargs
printf '%s\0' ./*.imputed.*_info | xargs -0 awk '$5 >= 0.5' >snplist.txt
これにより、ファイル名のリストが生成され、printf
null で終わるリストに渡されます。xargs
ユーティリティxargs
はそれを受け取りawk
始めます。できるだけ一度、一括して。パイプライン全体の出力はにリダイレクトされますsnplist.txt
。
この回避策は、ユーザーがNULLで終わる入力を読み取るための非標準オプションを実装するコマンドを持つxargs
LinuxなどのUnixを使用していると仮定します。また、シェルを使用しているとします。xargs
-0
bash
組み込み printf
ユーティリティ(ksh
OpenBSDのデフォルトシェルには組み込みユーティリティがないため、ここでは機能しません)。
zsh
シェルの場合(つまり、ないbash
):
autoload -U zargs
zargs -- ./*.imputed.*_info -- awk '$5 >= 0.5' >snplist.txt
これは基本的にロード可能なシェル関数をzargs
再実装したものです。詳細については、(関数のロード後)とドキュメントを参照してください。xargs
zsh
zargs --help
zshcontrib(1)