递归grep不同文件中的唯一模式

时间:2016-03-13 11:38:31

标签: linux unix grep find

抱歉标题不是很清楚。 所以,假设我正在为这样的网址递归地加入:

grep -ERo '(http|https)://[^/"]+' /folder

并且在文件夹中有几个包含相同网址的文件。我的目标是只输出一次这个网址。我试图将grep传递给| uniq或sort -u但没有帮助

示例结果:

/www/tmpl/button.tpl.php:http://www.w3.org
/www/tmpl/header.tpl.php:http://www.w3.org
/www/tmpl/main.tpl.php:http://www.w3.org
/www/tmpl/master.tpl.php:http://www.w3.org
/www/tmpl/progress.tpl.php:http://www.w3.org

3 个答案:

答案 0 :(得分:0)

如果输出结构总是如此: /some/path/to/file.php:http://www.someurl.org

您可以使用命令cut

cut -d ':' -f 2-应该有效。基本上,它将每一行切割成由分隔符(此处为“:”)分隔的字段,并选择第二个和后面的字段(-f 2 - )

之后,您可以使用uniq进行过滤。

答案 1 :(得分:0)

管道到Awk:

grep -ERo 'https?://[^/"]+' /folder |
awk -F: '!a[substr($0,length($1))]++'

基本的Awk成语!a[key]++在我们第一次看到key时是真的,在此之后永远是假的。将URL(或合理的近似值)提取到密钥中需要一些额外的技巧。

如果密钥是我们以前从未见过的密钥,则打印整个输入行,即它将从grep输出中打印文件名和第一次出现的URL。

在Awk中做整件事也不应该太难。

答案 2 :(得分:0)

如果你只想要地址而不想要找到它的文件,那么有一个grep选项-h来抑制文件输出;然后,列表可以通过管道传送到sort -u,以确保每个地址只出现一次:

$ grep -hERo 'https?://[^/"]+' folder/ | sort -u
http://www.w3.org

如果您不想要https?://部分,则可以使用Perl正则表达式(-P代替-E)并使用可变长度的后台({{1} }):

\K