2011-01-14 55 views
0

我正在使用Debian/GNU Linux OS并且喜欢使用短shell命令(终端或extern脚本)。grep:将每行中一个或多个单词的列表与文本文件进行比较

我的目标:我有一个像

在foo.txt的单词列表---- ---- foo.txt的

dog 
cat 
mouse with hat 

---- /foo.txt - -

并希望将此列表与bar.txt进行比较(意味着包含一些段落的普通文本)。

我想有两种比赛:

  1. 每一行的所有单词应该匹配(例如,“帽子鼠标”以及刚刚“帽子”)

  2. 只有每条整行的首次出现应该匹配

第一个问题相关:

我的第一个代码(到目前为止的命令行),我的问题:

for i in foo.txt; do fgrep -f foo.txt bar.txt 

只是匹配列表的第一个字。 现在,我想我有使用类似

for i in foo.txt; do fgrep -e <some-kind-of-regexp> -f foo.txt bar.txt 

但我陷入了与正则表达式:(

涉及到的第二个问题 对于停止的grep我只知道-m选项。先用任何比赛后

for i in foo.txt; do fgrep -m 1 -f foo.txt bar.txt 

停止。但我喜欢有像“搜索任何的第一场比赛和浏览整个列表后停止”。

回答

1

对于您的第一个问题,您需要在将它列入grep之前将列表拆分为单个单词。我为此使用了awk,但您也可以使用sed。我对分裂空白,但你可以很容易地在非字母数字拆分如果这就是你想要的东西:

fgrep -f <(mawk 'BEGIN{FS=" "}{print; if(NF > 1)for(i=1; i<=NF; i++)print $i}' foo.txt) bar.txt 

你的第二个问题,你需要获得一点点花哨。首先,输出行号以及每个匹配的字符串,然后您可以在匹配的字符串上唯一地获取与每个字符串匹配的行号。

cat bar.txt \ 
| mawk '{print NR,$0}' \ 
| join -1 1 -2 1 - <(fgrep -o -n -f <(mawk 'BEGIN{FS=" "}{print; if(NF > 1)for(i=1; i<=NF; i++)print $i}' foo.txt) bar.txt \ 
| sort -k2,2 -k1,1n \ 
| sort -k2,2 -us \ 
| cut -f1 \ 
| sort -k1,1) 
相关问题