如何为同一命令不重复地grep行?

如何为同一命令不重复地grep行?,grep,Grep,我有一个以空格分隔的文件,如下所示: $ cat in_file GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1 Chal_sti_synt_C GCF_000046845.1_ASM4684v1_protein.faa WP_004927566.1 Chal_sti_synt_C GCF_000046845.1_ASM4684v1_protein.faa WP_004919950.1 FAD_binding_3 GCF_00004684

我有一个以空格分隔的文件,如下所示:

$ cat in_file
GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1 Chal_sti_synt_C
GCF_000046845.1_ASM4684v1_protein.faa WP_004927566.1 Chal_sti_synt_C
GCF_000046845.1_ASM4684v1_protein.faa WP_004919950.1 FAD_binding_3
GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1 FAD_binding_3
$ cat out_file
GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1 Chal_sti_synt_C
GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1 FAD_binding_3
我正在使用以下shell脚本利用grep搜索字符串:

$ cat search_script.sh
grep "GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1" Pfam_anntn_temp.txt
grep "GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1" Pfam_anntn_temp.txt
问题是,我希望每个grep命令只返回它找到的字符串的第一个实例,而不返回前一个相同grep命令的输出

我需要一个如下所示的输出:

$ cat in_file
GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1 Chal_sti_synt_C
GCF_000046845.1_ASM4684v1_protein.faa WP_004927566.1 Chal_sti_synt_C
GCF_000046845.1_ASM4684v1_protein.faa WP_004919950.1 FAD_binding_3
GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1 FAD_binding_3
$ cat out_file
GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1 Chal_sti_synt_C
GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1 FAD_binding_3
其中第1行专用于第一个grep命令的输出,第2行专用于第二个grep命令的输出。我该怎么做


另外,我在一个大于125000行的大文件上运行这个。因此,search_script.sh主要由独特的grep命令组成。正是相同命令的执行打乱了我的下游分析。

如果我答对了问题,并且您希望根据每行的最后一个字段删除重复项,请尝试以下操作。这对于awk来说应该是一项简单的任务


我假设您正在根据in_文件的内容自动生成search_script.sh。如果您可以计算重复同一grep命令的次数,您可以只使用grep一次,然后使用head,例如,如果您知道您将使用它两次:

grep "foo" bar.txt | head -2
将在bar.txt中输出前2次出现的foo

如果必须单独执行grep命令,例如,如果grep命令之间有其他代码,则可以混合使用head和tail:

head-n显示输入的前n行 tail-n显示输入的最后n行 如果您确实必须始终使用相同的命令,但要确保输出始终不同,那么我能想到的实现这一点的唯一方法是使用临时文件和复杂的命令序列:

 cat foo.bar.txt.tmp 2>&1 | xargs -I xx echo "| grep -v \\'xx\\' " | tr '\n' ' '  | xargs -I xx sh -c "grep 'foo' bar.txt xx | head -1 | tee -a foo.bar.txt.tmp"
为了解释这个命令,将foo作为搜索字符串,bar.txt作为文件名,然后foo.bar.txt.tmp是临时文件的唯一名称。临时文件将保存已输出的字符串:

cat foo.bar.txt.tmp 2>&1:输出临时文件的内容。如果不存在,将向stdout输出一条错误消息,这很重要,因为如果输出为空,则命令的其余部分将无法工作。 xargs-I xx echo | grep-v\\'xx\\'将| grep-v添加到临时文件中每行的开头,grep-v something排除包含某物的行。 tr'\n''将换行符替换为空格,以便在单个字符串上具有grep-vs序列。 xargs-I xx sh-c grep'foo'bar.txt xx | head-1 | tee-a foo.bar.txt.tmp运行一个新命令grep'foo'bar.txt xx | head-1 | tee-a foo.bar.txt.tmp,用以前的输出替换xx。xx应该是排除先前输出的grep-vs序列。 head-1确保一次只输出一行 tee-foo.bar.txt.tmp将新输出附加到临时文件。
请务必清除脚本末尾的临时文件rm*.tmp。

@WiktorStribiżew我已经讨论了这个问题及其答案。我的问题是不同的,这个问题的答案不符合我的目的。我取消了接近投票。我想你不需要重复这个命令。使用它一次,获取所有匹配项,然后你可以对它们进行迭代。正如@WiktorStribiżew建议的那样,只运行一次grep并将结果放入数组中,然后依次使用它们遍历数组。。。请参阅这里的第2点,并将您的grep替换为my_命令