如何在文件中搜索列表中的每个条目并为每个条目打印一个新文件

如何在文件中搜索列表中的每个条目并为每个条目打印一个新文件

我有一个文件 ( list_file),它是名称列表,另一个文件 ( data_file) 包含数十万行文本,每行都以list_file.我想搜索以data_file每个名称开头的所有行,list_file并将每个名称的行导出到一个新文件*.txt*列表中的名称在哪里)

我有这个

grep -f "list_file" data_file > out.txt

但这不会将列表中的每一行分成自己的文件。

样本list_file

100_fullA
100_fullB
105_fullA
105_fullB
112_fullA
112_fullB
121_fullA
121_fullB

样本data_file

100_fullA NGATCATCGACAC
100_fullB NGATCATCGACAC
105_fullA NGATCATCGACAC
105_fullB NGATCATCGACAC
112_fullA NGATCATCGACAC
112_fullB NGATCATCGACAC
121_fullA NGATCATCGACAC

答案1

您可以从 构造一个查找表(或哈希)list_file,例如在 中使用关联数组awk

awk 'NR==FNR {list[$1]=1; next} $1 in list {print > $1".txt"}' list_file data_file

输出将保存在 files 中100_fullA.txt100_fullB.txt依此类推。

答案2

您可以通过动态构建命令来做到这一点:

grep -f list_file data_file | sed -e "s/^\([^ ]*\).*/echo '&' >> \1;/" | sh

答案3

这是使用 Bash 的解决方案:

#!/bin/bash

while read pointer; do
 filename="$(echo $pointer | cut -d ' ' -f 1)" 
 if grep $filename list_file > /dev/null; then
  echo $pointer >> output/"$filename".txt
 fi
done < data_file

这是逐行细分:

  • 第 3 行是用于循环访问 data_file 的 while 循环的开始。

  • 第 4 行回显当前迭代中读取的行。然后该行被传递到 cut,它使用空格作为分隔符来剪切该行的第一部分。然后将结果分配给名为“文件名”的变量。

  • 第 5 行使用 grep 来确定 list_file 中是否存在先前确定的值。如果 grep 成功找到该值(返回状态 0),则脚本继续执行第 6 行。如果 grep 未找到任何内容(返回状态 1),则脚本重新开始循环。

  • 第 6 行将整行回显到输出/“$filename”.txt。

  • 第 7 行结束 if 语句。

  • 第 8 行结束循环,并且是引用 data_file 的地方。

其他重要注意事项:

  • “output/”目录必须在脚本运行之前创建,否则你会得到类似“output: no such file or directory”的错误。如果这是一个问题,可以通过在脚本开头添加“mkdir output”来轻松解决。
  • 您提到 data_file 有数十万行。因此,该脚本可能需要很长时间才能完成。如果您发现自己经常查询此文件以获取信息,则值得将这些信息转换为 MariaDB 或类似的数据库。
  • 如果 list_file 还包含许多条目,则该脚本将花费非常长的时间来运行,因为第 5 行的 grep 会在循环的每次迭代中查询整个 list_file。同样,这个问题可以通过 SQL 数据库中的可用工具来解决。

相关内容