【问题标题】:Recursively grep unique pattern in different files递归 grep 不同文件中的唯一模式
【发布时间】:2016-03-13 11:38:31
【问题描述】:

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

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

在文件夹中有几个包含相同 url 的文件。我的目标是只输出一次这个网址。我试图通过管道将 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

【问题讨论】:

  • grep 输出什么?你能举一些例子吗?
  • 你需要去掉 ":" 之前的部分,它们不是唯一的,那么你就只有你的 URL。尝试通过管道连接到 awk,然后再连接到 uniq。我很快就会自己尝试这样做。
  • 嗯,是的,我也在考虑,但如果我需要这个职位怎么办?
  • 所以,这将只打印唯一的 URL,但我不确定您如何做到这一点并且仍然保留所有数据,至少不是一次性的。 grep -ERo '(http|https)://[^/"]+' /folder | awk -F ":" '{print $2$3}' | uniq。这很粗糙,但如果grep 的输出格式一致,它应该可以工作。
  • 您的示例输出多次包含相同的 URL,而您的所有问题看起来就像您只想检索每个 URL 的第一次出现。是哪个?

标签: linux unix grep find


【解决方案1】:

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

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

如果您不想要 https?:// 部分,您可以使用 Perl 正则表达式(-P 而不是 -E)和可变长度后视(\K):

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

【讨论】:

    【解决方案2】:

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

    你可以使用命令cut

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

    之后就可以使用uniq进行过滤了。

    【讨论】:

      【解决方案3】:

      到 awk 的管道:

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

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

      如果键是我们以前从未见过的键,这将打印整个输入行,即它将打印来自grep 输出的每个 URL 第一次出现的文件名和 URL。

      在 awk 中完成所有事情也不应该太难。

      【讨论】:

        猜你喜欢
        • 2011-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多