【发布时间】:2014-06-04 10:37:52
【问题描述】:
当我过滤不包含指定字符串的行时,我使用
grep -v "specifiedstring" filename
但是如何过滤列表中不包含很多字符串的行。
非常感谢!
【问题讨论】:
-
我已经删除了我的答案,现在你已经解释了你的问题。您有 6000 个要排除的字符串。
标签: regex linux bash shell unix
当我过滤不包含指定字符串的行时,我使用
grep -v "specifiedstring" filename
但是如何过滤列表中不包含很多字符串的行。
非常感谢!
【问题讨论】:
标签: regex linux bash shell unix
你可以or多个字符串:
grep -v "string1\|string2\|string3" filename
这将排除包含string1、string2、string3 的行。
在基本正则表达式(以上版本)中,正则表达式元字符失去了特殊意义,需要转义。
使用扩展正则表达式,您无需转义|:
grep -Ev "string1|string2|string3" filename
如果列表包含在文件中,请使用-f 选项:
grep -v -f list_to_exclude filename
如 cmets 中所述,如果模式是一组字符串,您可以提供 -F 选项以加速 grep:
grep -F -v -f list_to_exclude filename
来自手册:
-F, --fixed-strings
Interpret PATTERN as a list of fixed strings, separated by
newlines, any of which is to be matched. (-F is specified by
POSIX.)
下面的例子应该进一步解释它。给定一个输入文件,比如input.txt:
This is line.
This is line2.
This is line3.
This is line4.
This is line*.
现在使用命令:
grep -v 'line*' input.txt
不会产生任何结果,因为 模式 line* 被解释为正则表达式,并将匹配给定输入文件中的所有行,而 -v 反转匹配。如果 line* 是 固定字符串 而不是正则表达式,则提供 -F 选项,即:
grep -F -v 'line*' input.txt
会产生:
This is line.
This is line2.
This is line3.
This is line4.
此外,由于grep 现在不是在寻找模式,而是寻找固定字符串,因此它比不使用-F 选项要快得多。
【讨论】:
| 分开不是一个好的解决方案
-f。请参阅上面的编辑。
-F:grep -F -v -f list filename
你可以AND几个字符串用grep
grep -v "string1.*string2" file
这将过滤掉包含 string1 和 string2 的行,而留下仅包含 string1 或 string2 的行
【讨论】:
如果您从其他命令而不是从文件中获取列表:
grep -F -v -f <(get_list_to_exclude) <(get_list_to_filter)
注意:如果排除输出为空,则 grep 失败(因为单个空行匹配过滤列表中的任何行)。
如果列表已排序,则可以使用comm 实用程序。它不会因排除列表为空而失败。
comm -- 选择或拒绝两个文件共有的行
两个示例文件:
$ cat a
a
b
c
$ cat b
a
z
comm可以通过以下方式过滤列表:
# exclude b from a
$ comm -2 -3 a b
b
c
# exclude a from b
$ comm -1 -3 a b
z
流的语法相同:
$ comm -2 -3 <(cat a) <(cat b)
b
c
请参阅man comm 了解更多说明。
【讨论】: