使用 bash 和 awk 删除不包含字符串列表之一的行
Using bash and awk to delete lines that don't include one of a list of strings
我有一个非常大的文本文件,myReads.sam,看起来像这样:
J00118:315:HMJWTBBXX:4:1118:21684:2246 4 * 0 0 * * 0 0 CR:Z:TTTGTCATCTGTTTGT
J00118:315:HMJWTBBXX:4:2211:19532:14449 4 * 0 0 * * 0 0 CR:Z:TATGTCATCTTTCCTC
我有另一个 500 行的文本文件,myIDs.txt,它看起来像这样:
CR:Z:TTTGTCATCTGTTTGT
CB:Z:CTACCCAGTCGACTGC
QT:Z:AAFFFJJJ
我想创建第三个文本文档 myFilteredReads.sam,它排除了不包含 myIDs.txt 中任一字符串的任何行。因此,例如,如果我使用上面的 myReads.sam 和 myIDs.txt 片段应用此过滤器,新文件将如下所示:
J00118:315:HMJWTBBXX:4:1118:21684:2246 4 * 0 0 * * 0 0 CR:Z:TTTGTCATCTGTTTGT
我知道如果我只过滤单个字符串(例如 'CR:Z:TTTGTCATCTGTTTGT'),我可以像这样使用 awk:
cat myReads.sam | awk '!/CR:Z:TTTGTCATCTGTTTGT/' > myPartiallyFilteredReads.sam
不过,我不确定如何命令 awk 将引号中的部分替换为文件的每一行。我想我可以尝试循环浏览文件:
cat myIDs.txt | awk 'BEGIN {i = 1; do { !/i/; ++i } while (i < 500) }' myReads.sam > myFilteredReads.sam
...但这对我不起作用。
有什么建议吗?提前致谢。
你有一个非常简单的方法来完成你正在尝试的事情。 grep
允许从文件中读取模式,-v
选项反转匹配。因此,您可以简单地找到 myFilteredReads.sam
中不包含 myIDs.txt
和
中的模式的所有行
grep -v -f myIDs.txt myFilteredReads.sam
例子Use/Output
使用您在 data.txt
中的数据和您在 filter.txt
中的 ID,您会得到想要的结果,例如
$ grep -v -f filter.txt data.txt
J00118:315:HMJWTBBXX:4:2211:19532:14449 4 * 0 0 * * 0 0 CR:Z:TATGTCATCTTTCCTC
编辑 -- 如果您只想要 myIDs.txt
中的行
然后删除-v
,例如
$ grep -f filter.txt data.txt
J00118:315:HMJWTBBXX:4:1118:21684:2246 4 * 0 0 * * 0 0 CR:Z:TTTGTCATCTGTTTGT
抱歉,我误解了你的意思 include/exclude。
main 是包含内容的文件
str 是带有 'interesting strings'
的文件
out 是输出文件
#!/bin/bash
while read line; do
grep ${line} main >> out
done < str
我有一个非常大的文本文件,myReads.sam,看起来像这样:
J00118:315:HMJWTBBXX:4:1118:21684:2246 4 * 0 0 * * 0 0 CR:Z:TTTGTCATCTGTTTGT
J00118:315:HMJWTBBXX:4:2211:19532:14449 4 * 0 0 * * 0 0 CR:Z:TATGTCATCTTTCCTC
我有另一个 500 行的文本文件,myIDs.txt,它看起来像这样:
CR:Z:TTTGTCATCTGTTTGT
CB:Z:CTACCCAGTCGACTGC
QT:Z:AAFFFJJJ
我想创建第三个文本文档 myFilteredReads.sam,它排除了不包含 myIDs.txt 中任一字符串的任何行。因此,例如,如果我使用上面的 myReads.sam 和 myIDs.txt 片段应用此过滤器,新文件将如下所示:
J00118:315:HMJWTBBXX:4:1118:21684:2246 4 * 0 0 * * 0 0 CR:Z:TTTGTCATCTGTTTGT
我知道如果我只过滤单个字符串(例如 'CR:Z:TTTGTCATCTGTTTGT'),我可以像这样使用 awk:
cat myReads.sam | awk '!/CR:Z:TTTGTCATCTGTTTGT/' > myPartiallyFilteredReads.sam
不过,我不确定如何命令 awk 将引号中的部分替换为文件的每一行。我想我可以尝试循环浏览文件:
cat myIDs.txt | awk 'BEGIN {i = 1; do { !/i/; ++i } while (i < 500) }' myReads.sam > myFilteredReads.sam
...但这对我不起作用。
有什么建议吗?提前致谢。
你有一个非常简单的方法来完成你正在尝试的事情。 grep
允许从文件中读取模式,-v
选项反转匹配。因此,您可以简单地找到 myFilteredReads.sam
中不包含 myIDs.txt
和
grep -v -f myIDs.txt myFilteredReads.sam
例子Use/Output
使用您在 data.txt
中的数据和您在 filter.txt
中的 ID,您会得到想要的结果,例如
$ grep -v -f filter.txt data.txt
J00118:315:HMJWTBBXX:4:2211:19532:14449 4 * 0 0 * * 0 0 CR:Z:TATGTCATCTTTCCTC
编辑 -- 如果您只想要 myIDs.txt
然后删除-v
,例如
$ grep -f filter.txt data.txt
J00118:315:HMJWTBBXX:4:1118:21684:2246 4 * 0 0 * * 0 0 CR:Z:TTTGTCATCTGTTTGT
抱歉,我误解了你的意思 include/exclude。
main 是包含内容的文件
str 是带有 'interesting strings'
的文件out 是输出文件
#!/bin/bash
while read line; do
grep ${line} main >> out
done < str