我有一个文件,其内容类似于:
google.com,9,AB+CD,nonAB+nonCD
youtube.com,9,AB+CD,AB+CD
facebook.com,20,AB+CD,nonCD
列数不固定。但第一列是 URL,第二列是数字,从第三列开始是用逗号分隔的关键字,但每个网站都不同。
我想计算 URL(行)的数量,以便控制行中的关键字。例如,
1)AB+CD
没有nonAB
and nonCD
。注意:AB+CD 这个词可以出现多次。2) AB+CD 没有出现nonCD
(但如果有其他内容也可以)
如何在一行中搜索一个字符串并确保不存在另一个字符串。当我使用:
grep 'AB+CD' test.txt > result.txt
它打印出找到“AB+CD”的每一行。
如果我想打印只有“AB+CD”的行,该怎么办:
youtube.com,9,AB+CD,AB+CD
或者将 'AB+CD' 与 'nonAB' 以外的任何其他项组合在一起,得到:
youtube.com,9,AB+CD,AB+CD
facebook.com,20,AB+CD,nonCD
答案1
如果您只是想要进行纯文本搜索而不关心列,则可以grep -v
像这样链接反向匹配:
cat input.txt | grep 'IncludedText' | grep -v 'ExcludedText'
如果您想按列进行适当的过滤,您可能需要使用类似的东西awk
。
答案2
一般技巧:
包含以下内容的行
foo
以及包含bar
(foo OR bar
) 的行:grep -e foo -e bar
在同一行中包含
foo
和 的行( ):bar
foo AND bar
grep foo | grep bar
不包含
baz
(NOT baz
) 的行:grep -v baz
使用这些积木,您可以构建逻辑。问题-v
不仅限于单个模式,而是全局性的grep
(至少在我的 Debian 中)。这使得以下操作成为NOT (foo OR bar)
可能:
grep -v -e foo -e bar
这相当于(NOT foo) AND (NOT bar)
:
grep -v foo | grep -v bar
然而NOT (foo AND bar)
(逻辑上等同于(NOT foo) OR (NOT bar)
)并不那么容易。我们可以尝试foo AND bar
用单身的(扩展)grep
:
再次在同一行中包含
foo
和 的行( ):bar
foo AND bar
grep -E 'foo.*bar|bar.*foo'
现在得到NOT (foo AND bar)
:
grep -v -E 'foo.*bar|bar.*foo'
我不确定上面的方法在处理两种以上模式时是否是一个完整的系统。但你的一些问题仍然可以用它解决。例如:
AB+CD
无nonAB
和nonCD
如果我没理解错的话AB+CD AND NOT (nonAB OR nonCD)
grep AB+CD | grep -v -e nonAB -e nonCD
请注意,这个请求使事情变得复杂:
我想打印只有“AB+CD”的行
有人可能会说grep ,AB+CD,AB+CD
可以,但是由于“列数不固定”,我想你会想区分这两行:
youtube.com,9,AB+CD,AB+CD,AB+CD
youtube.com,9,AB+CD,AB+CD,banana
在这种情况下,您需要更复杂的正则表达式或其他工具(如awk
)。
答案3
虽然你会在这里得到答案,但你应该看看人grep(可能会让人不知所措)和一些例子。暂时,答案如下:
使用grep
grep "foobar" test.txt
foobar
将在文件中搜索包含单词的行test.txt
并显示所有出现的情况,而
grep "foo" -v "bar" test.txt
将搜索包含单词foo
但不包含单词的行bar
。我们得到这个是因为-v
开关手册页解释如下:
-v, --invert-match
Invert the sense of matching, to select non-matching lines.
(-v is specified by POSIX .)
这只是意味着它将搜索包含这些单词的行(此处bar
),但最终显示时会排除它们。因此反转搜索。
另外,要计算与搜索匹配的行数,请使用-c
转变 :
-c, --count
Suppress normal output; instead print a count of matching lines
for each input file. With the -v, --invert-match option (see below),
count non-matching lines. (-c is specified by POSIX .)
作为自我练习,尝试使用 grep 搜索文件福巴。
答案
搜索AB+CD
忽略nonAB
和nonCD
计数 URL:
grep "AB+CD" test | grep -cve "non"
此处-v "non"
将忽略nonAB
和 ,nonCD
因为它们都包含non
在内。 并且-c
将给出匹配总数,而不是打印它们。 要打印匹配的行,只需忽略-c
。
您可以将其用于单独的反转:
grep "AB+CD" test | grep -cve "nonAB\|nonCD"
其中\|
代表OR
和 意味着nonAB
或nonCD
精确的指定的单词-e
转变。
建议你参见 Kamil 的回答,尽可能多地阅读手册页(您知道命令),努力在线搜索资料并为社区服务。请随意添加更多详细信息以进行回答。