Vio*_*laW 6 osx grep awk text-processing
我对命令行工具仍然很陌生(使用我的 Mac OSX 终端),希望我没有错过其他地方的答案,但我已经搜索了几个小时。
我有一个包含 3 个字符串的 200 个组合的文本文件(我们称之为 strings.txt)。[编辑 2017/01/30 ] 前五行如下所示:
"surveillance data" "surveillance technology" "cctv camera"
"social media" "surveillance techniques" "enforcement agencies"
"social control" "surveillance camera" "social security"
"surveillance data" "security guards" "social networking"
"surveillance mechanisms" "cctv surveillance" "contemporary surveillance"
Run Code Online (Sandbox Code Playgroud)
请注意,我可以将 strings.txt 更改为任何其他格式,只要第 1 行中的监视数据之类的 bigrams/2-word 短语保持在一起。(这意味着我可以在必要时删除引号,至于下面@MichaelVehrs 的答案)。
现在我想在一个包含 800 多个文件的目录中搜索那些至少包含一个字符串组合(文件中的任何位置)的文件。我最初的想法是将 egrep 与这样的模式文件一起使用:
egrep -i -l -r -f strings.txt file_directory
Run Code Online (Sandbox Code Playgroud)
但是,如果每行有一个字符串,我只能让它工作。这是不可取的,因为我需要标识的文件包含给定模式的所有三个字符串。有没有办法向 grep 模式文件添加某种 AND 运算符?或者是否有另一种方法可以使用其他功能/工具来实现我想要的?非常感谢!
下面@MichaelVehrs 的回答非常有帮助;我将其编辑为以下内容:
while read one two three four five six
do grep -ilFr "$one $two" *files* | xargs grep -ilFr "$three $four" | xargs grep -ilFr "$five $six"
done < *patternfile* | sort -u
Run Code Online (Sandbox Code Playgroud)
当模式文件包含不带引号的字符串时,此答案有效。可悲的是,它似乎只匹配模式文件第一行的模式。有谁知道为什么?
之前有人问过一个关于 grepping 多个值的类似问题,但我需要AND
逻辑来匹配其他文件中模式文件 strings.txt 中的三个字符串组合之一。我意识到可能需要更改 strings.txt 的格式才能使匹配工作,并希望得到建议。
由于agrep
您的系统中似乎不存在,请查看基于 sed 和 awk 的替代方案,以应用 grep 和本地文件读取的模式进行操作。
PS:由于您使用 osx,我不确定您拥有的 awk 版本是否支持以下用法。
awk
可以用多种模式的 AND 操作来模拟 grep 的用法:
awk '/pattern1/ && /pattern2/ && /pattern3/'
所以你可以这样转换你的模式文件:
$ cat ./tmp/d1.txt
"surveillance data" "surveillance technology" "cctv camera"
"social media" "surveillance techniques" "enforcement agencies"
"social control" "surveillance camera" "social security"
"surveillance data" "security guards" "social networking"
"surveillance mechanisms" "cctv surveillance" "contemporary surveillance"
Run Code Online (Sandbox Code Playgroud)
对此:
$ sed 's/" "/\/ \&\& \//g; s/^"/\//g; s/"$/\//g' ./tmp/d1.txt
/surveillance data/ && /surveillance technology/ && /cctv camera/
/social media/ && /surveillance techniques/ && /enforcement agencies/
/social control/ && /surveillance camera/ && /social security/
/surveillance data/ && /security guards/ && /social networking/
/surveillance mechanisms/ && /cctv surveillance/ && /contemporary surveillance/
Run Code Online (Sandbox Code Playgroud)
PS:您可以使用>anotherfile
in the end 将输出重定向到另一个文件,或者您可以使用该sed -i
选项在同一搜索词模式文件中进行就地更改。
然后你只需要从这个模式文件中向 awk 提供 awk 格式的模式:
$ while IFS= read -r line;do awk "$line" *.txt;done<./tmp/d1.txt #d1.txt = my test pattern file
Run Code Online (Sandbox Code Playgroud)
您也不能通过在原始模式文件的每一行中应用 sed 来转换原始模式文件中的模式,如下所示:
while IFS= read -r line;do
line=$(sed 's/" "/\/ \&\& \//g; s/^"/\//g; s/"$/\//g' <<<"$line")
awk "$line" *.txt
done <./tmp/d1.txt
Run Code Online (Sandbox Code Playgroud)
或者单行:
$ while IFS= read -r line;do line=$(sed 's/" "/\/ \&\& \//g; s/^"/\//g; s/"$/\//g' <<<"$line"); awk "$line" *.txt;done <./tmp/d1.txt
Run Code Online (Sandbox Code Playgroud)
上面的命令在我的测试文件中返回正确的 AND 结果,如下所示:
$ cat d2.txt
This guys over there have the required surveillance technology to do the job.
The other guys not only have efficient surveillance technology, but they also gather surveillance data by one cctv camera.
$ cat d3.txt
All surveillance data are locked.
All surveillance data are locked and guarded by security guards.
There are several surveillance mechanisms (i.e cctv surveillance, contemporary surveillance, etv)
Run Code Online (Sandbox Code Playgroud)
结果:
$ while IFS= read -r line;do awk "$line" *.txt;done<./tmp/d1.txt
#or while IFS= read -r line;do line=$(sed 's/" "/\/ \&\& \//g; s/^"/\//g; s/"$/\//g' <<<"$line"); awk "$line" *.txt;done <./tmp/d1.txt
The other guys not only have efficient surveillance technology, but they also gather surveillance data by one cctv camera.
There are several surveillance mechanisms (i.e cctv surveillance, contemporary surveillance, etv)
Run Code Online (Sandbox Code Playgroud)
更新:
上面的 awk 解决方案打印匹配的 txt 文件的内容。
如果您想显示文件名而不是内容,请在必要时使用以下 awk:
awk "$line""{print FILENAME}" *.txt
Run Code Online (Sandbox Code Playgroud)