嵌套 while 循环

嵌套 while 循环

我使用以下命令来匹配 中的一些 IDfile 1并检索 中存储的数据referencefile

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

我有 50 个与 file1 类似的文件存储在一个目录中,并且想要对所有这些文件执行上述命令并将输出保存为单独的文件。有没有一种方法可以通过一个命令(例如嵌套循环)来实现这一目标。

参考文件

>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

您可以将对 xargs + grep 的调用包装在 for 循环中。请注意,输出的顺序可能与 file1 中的输入不匹配,因为 grep 将按照参考文件中看到的顺序进行捕获。

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

相关内容