Forループはディレクトリツリーを繰り返し、同じ名前のファイルから結果を抽出します。 [閉じる]

Forループはディレクトリツリーを繰り返し、同じ名前のファイルから結果を抽出します。 [閉じる]

一連のディレクトリがすべてlist.txt同じ形式になっており、結果をファイルに保存したいと思います。各ディレクトリツリーを繰り返し探索し、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.txtNameoutput.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

すべての項目を単一のファイルに保存したい場合は、最後のコマンドは次のようになります。

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ファイル名 globbing パターンがあまりにも多くの名前に拡張されると、繰り返しが必要になります。

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

関連情報