ディレクトリツリーを反復処理して同じ名前のファイルから結果を抽出する for ループ

ディレクトリツリーを反復処理して同じ名前のファイルから結果を抽出する for ループ

一連のディレクトリがあり、すべてlist.txt同じ形式になっています。結果を 1 つのファイルにまとめたいと考えています。各ディレクトリ ツリーを繰り返し移動し、list.txt以下の grep/awk パイプラインを使用して、ファイルから周囲のテキストなしで特定の列を抽出し、それぞれの出力を同じファイルに書き込むスクリプトを作成したいと考えています。

    grep 'bar[0-9]' file.txt | awk '{print $1}'

次のことを試みましたが、スクリプト内のループのどこで問題が発生しているか正確にはわかりません。

#!/bin/bash
##Extract ligands from toplist and concatenate to file
for i in /home/ubuntu/Project/working/library_*/Results/list.txt
do
    grep 'bar[0-9]' i | awk '{print $1}' | cat ../output.txt i
done

ディレクトリツリーは次のようになります。

.
├── library_1-200
│   ├── Results
│   │   ├── complex
│   │   ├── sorted.txt
│   │   └── list.txt
│   ├── files
│   │   ├── output
│   │   └── txt
│   └── summary.txt
├── library_201-400
│   ├── Results
│   │   ├── complex
│   │   ├── sorted.txt
│   │   └── list.txt
│   ├── files
│   │   ├── output
│   │   └── txt
│   └── summary.txt
├── library_401-600
│   ├── Results
│   │   ├── complex
│   │   ├── sorted.txt
│   │   └── list.txt
│   ├── files
│   │   ├── output
│   │   └── txt
│   └── summary.txt
└── library_601-800
    ├── Results
    │   ├── complex
    │   ├── sorted.txt
    │   └── list.txt
    ├── files
    │   ├── output
    │   └── txt
    └── summary.txt

のサンプルlist.txt。ここでは、Name値を入力するだけです。output.txt

Name    Score
bar65    -7.8 
bar74    -7.5 
bar14    -7.5 
bar43    -7.4 
bar94    -7.4 
bar16    -7.4 
bar12    -7.3 
bar25    -7.3 
bar65    -7.3 
bar76    -7.3 
bar24    -7.3 
bar13    -7.3 
bar58    -7.2 
bar68    -7.2 
bar28    -7.2 

解決策は、以前はiだけだったところに「$i」を入れて、| cat >> ../output.txt

答え1

grep コマンドではi、 の代わりに を使用しています。$i

そして、これらすべてを 1 つのファイルにまとめたい場合、最後のコマンドは次のようになります。

cat >> /home/ubuntu/Project/working/output.txt

あるいは単に:

>> /home/ubuntu/Project/working/output.txt

答え2

元のコード内のいくつかの小さなタイプミスを修正する ("$i"の代わりにを使用しi、出力を出力ファイルにリダイレクトして、その内容を出力しようとするのではなく) 以外に、これらのファイルが何千個もない場合は、次の操作を行いますlist.txt

awk '/^bar[0-9]/ { print $1 }' /home/ubuntu/Project/working/library_*/Results/list.txt >output.txt

awkこれは、文字列 で始まり、数字が続くすべての行の最初の列を抽出するためにを使用していますbar。これは、パターン に一致するすべてのファイルに対して実行されます/home/ubuntu/Project/working/library_*/Results/list.txt。抽出されたデータは にリダイレクトされますoutput.txt

/home/ubuntu/Project/working/library_*/Results/list.txtファイル名のグロブ パターンが拡張されて名前が多すぎる場合は、ループが必要になります。

for pathname in /home/ubuntu/Project/working/library_*/Results/list.txt; do
    awk '/^bar/ { print $1 }' "$pathname"
done >output.txt

出力をリダイレクトする方が効率的であることに注意してくださいループ個々のawk呼び出しよりも。また、必要な行を検出するawk作業が簡単に実行され、それが不要であることに注意してください。grepcat

awk最初の行を除くすべての行の最初の列が必要な場合 (サンプル データのように)、コード内の条件を から に変更でき/^bar[0-9]/ますFNR > 1

関連情報