从 bash 中的列表运行多个管道 grep 命令

从 bash 中的列表运行多个管道 grep 命令

作为安全工作的一部分,我每天使用 sqlite3 通过 SSH 分析数十个 Google Chrome 历史文件。

每个用户都可以导航到几十个授权的“安全”站点。就我的目的而言,我不关心这些安全网站。为了列出每个历史文件的 URL 并忽略安全网站,我使用grep -v并列出每个安全网站,如下所示:

sqlite3 /home/me/HistoryDatabaseFile.db "select * from urls order by url;" | grep -v safesite1.com | grep -v safesite2.com | grep -v safesite3.com | grep -v safesite4.com

等等。我的命令已经增长到至少 20 行并且变得难以管理。有什么方法可以显示用户的 URL 列表,同时以列出的格式排除我的安全网站?我正在想象这样的事情:

safesite1.com
safesite2.com
safesite3.com

然后将该列表带入命令中。它可以是内部的或外部的——我并不关心,只要它最终在 bash 中输出即可。

感谢你给与我的帮助!

答案1

我认为你正在寻找的是类似的东西

grep -vf safe_websites inputfile

-v反转你已经知道的匹配,-f就是从文件中获取模式safe_websites

答案2

您可以考虑的另一个选择是使用egrepgrep 的形式,它允许您使用扩展正则表达式,这样您就可以将多个目标放入单个字符串中:

egrep -v "safesite1\.com|safesite2\.com|safesite3\.com"

这些和其他扩展 RE 的详细信息可以从 获得man 7 re_format

答案3

如前所述,您应该使用 选项-f,并提供要使用的grep模式列表。grep

但是,您还提到 URL 中包含特殊字符,这是有道理的。正确的答案是使用-F标志来grep仅将模式视为固定字符串。

所以要完成你想要的:

首先,将安全网站列表放入文件中,例如/tmp/safelist.txt.这应该看起来像:

safesite1.com
safesite2.com
safesite3.com

接下来,grep像这样调用该文件:

sqlite3 /home/me/HistoryDatabaseFile.db "select * from urls order by url;" | grep -vFf /tmp/safelist.txt

答案4

事实证明我的问题与我试图解析的数据有关。如果我尝试使用测试输出

a
b
c
d
e

然后用它grep -vf file.txt来删除 a、b 和 c,它就像一个魅力。因为我试图忽略一堆带有各种特殊字符的网站,所以它对我来说从来没有用,即使在尝试操作我的 sql 查询的输出 .txt 文件时也是如此。

最终,为了使命令更具可读性,我的解决方案是使用反斜杠 ( \) 将命令拆分为多行,使其更易于阅读:

sqlite3 /home/me/HistoryDatabaseFile.db "select * from urls order by url;" | \
grep -v safesite1.com | \
grep -v safesite2.com | \
grep -v safesite3.com | \
grep -v safesite4.com | \
grep -v safesite5.com

谢谢大家的帮助!

相关内容