ネストされたwhileループ

ネストされたwhileループ

次のコマンドを使用して の一部の ID を照合し、 に保存されたfile 1データを検索しますreferencefile

while read -r line; do
    awk -v pattern=$line -v RS=">" '$0 ~ pattern { printf(">%s", $0); }' referencefile;
done <file1 >output

ディレクトリにfile1に似た50個のファイルが格納されており、これらすべてのファイルに対して上記のコマンドを実行し、出力を別々のファイルとして保存しようとしています。 1つのコマンド(ネストしたループなど)でこれを達成する方法はありますか?

参照文書

>LD200FFFFFFFFFFFFFFFFFFFFSSSSSSSSS
 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
 SSSSSSSSSSSSSSS
>LD400HHHHHHHHHHHHHHHHHHHHHHHHHHHHH
 HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
>LD311DDDDDDDDDDDDDDDDDDDDDDDDDDDDD
>LD500TTTTTTTTTTTTTTTTTTTTTTTTTTTTT
>LD100KKKKKKKKKKKKKKKKKKKKKKKKKKKKK

サンプルファイル1

LD100
LD200
LD311

予想出力1.txt

>LD100KKKKKKKKKKKKKKKKKKKKKKKKKKKKK
>LD200FFFFFFFFFFFFFFFFFFFFSSSSSSSSS
 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
 SSSSSSSSSSSSSSS
>LD311DDDDDDDDDDDDDDDDDDDDDDDDDDDDD

サンプルファイル2

LD500
LD400

予想出力2.txt

>LD500TTTTTTTTTTTTTTTTTTTTTTTTTTTTT
>LD400HHHHHHHHHHHHHHHHHHHHHHHHHHHHH
 HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

答え1

単一のコマンドラインを検索するのではなく、これを実行するためにスクリプトを使用していることを理解しています。それでは、スクリプトを次のように変更するのはどうですか?

#!/bin/bash
Directory="$1"
ls "$Directory" | while read FileName
do
  while read -r line
  do
   awk -v pattern="$line" -v RS=">" '$0 ~ pattern { printf(">%s", $0); }' referencefile;
  done < "$Directory"/"$FileName" > OutputDirectory/"$FileName".out
done

スクリプトは次のように呼び出す必要があります。

<script> <directory with input files>

使用に関するいくつかの注意事項:

  • 必ず存在しなければなりませんOutputDirectory。スクリプトで編集するか、パラメータを追加してください。
  • 入力ファイルのみを含める必要があり、<directory with input files>サブディレクトリは含めないでください。それ以外の場合は、エラーメッセージが表示されます。

警告する

スクリプトは解析に依存しますls。これにより、簡単に理解できるようにスクリプトを単純に保つことができますが、通常推奨しないこれは、ファイル名の特殊文字が望ましくない動作を引き起こす可能性があるためです。入力ファイルの名前があまりにも派手ではない単純な設定で動作します。名前にスペースを入れてもかまいませんが、たとえば名前に改行を使用するとエラーが発生し、そのファイルは処理されません。

答え2

通常、次のようにすることができます。

for f in file*; do
    while read ...; do
        some commands...
    done < "$f"
done > output

そうでなければ

cat file* | while read ...; do
    some commands...
done > output

欲しいならただ一致する行がある場合は、ファイルからパターンを読み取り、一致する行を印刷してgrepこれをより直接的に実行できます。grep -f

for patternfile in file*; do
    grep -f "$patternfile" referencefile
done

答え3

forループでxargs + grepへの呼び出しをラップできます。 grep は参照ファイルに示された順序でキャプチャされるため、出力順序が file1 の入力と一致しない可能性があります。

for f in file*;do
  < "$f" paste -sd\||\
      xargs -r -I{} grep -Pzo '(?m:(?:^[>](?:'{}')\D.*\n)(?:[^>].*\n)*)' reference.file | tr -d '\0' \
  > "$f.out"
done

関連情報