我使用以下命令来匹配 中的一些 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