【问题标题】:unix : search a file if a string is present between two patternsunix:如果两个模式之间存在字符串,则搜索文件
【发布时间】:2014-11-15 13:13:35
【问题描述】:

我有一个文件,格式如下。我想搜索一个词,例如'hello' 出现在模式之后和 DocName 之前的行中。如果它存在,有多少这样的模式有它? 如何使用 grep/awk/sed 在一行中执行此操作?

预期的输出是:假设我正在搜索单词 'hello' 是否存在,那么在这种情况下它存在于第 1、第 2 和第 4 个模式中,所以输出为 3,因为我们有三个 'hello' 存在于三个模式。请注意,即使在第一个模式中多次出现 'hello',它仍然算作一次。

:
:
:
DocName: abjrkj.txt
schema:
abs
askj
djsk
djsk
hello
adj
hello

DocName: abjrkj.txt
schema:
abs
askj
djsk
djsk
adj
hello

DocName: aasjrkj.txt
schema:
absasd
askjas
djsksa
djskasd
adjsg

DocName: ghhd.txt
schema:
absg
fdgaskj
dgdjsk
dgdfdjsk
drgadj
hello
:
:
:

【问题讨论】:

  • 上述输入的预期输出是什么?
  • @lanc 使用各种输入制作更好的示例并编写预期的示例输出
  • 我已经编辑了问题,看看。
  • @Lanc:过去你接受的答案太少(3/16)。
  • @lanc 计算 wc 是合适的选择!

标签: regex unix awk sed grep


【解决方案1】:

试试这个。

awk -F '^DocName:' '/hello/ { ++i }
    END { print i }' file

如果您绝对需要单行解决方案(为什么??),则可以将空格压缩为一个空格。

【讨论】:

  • 谢谢!!一句话,我暗示了一个紧凑的解决方案。
【解决方案2】:

这里是 sed 解决方案:

sed ':a; N; s/\n/ /; $!ba; s/DocName/\n&/g' < file | sed -n '/DocName/{/hello/p}' | wc

这是一种算法:它将整个文件放在模式空间中,用空格替换所有 \n 字符。然后在每个 DocName 字符串放置 \n 之前。之后是管道抛出搜索 Docname & hello 最终打印 3 个数字,其中第一个被询问。如果你想看到打印的行省略 |出于测试原因的厕所管道。也许更优雅的 sed 解决方案存在与模式和保持空间一起玩!

【讨论】:

    【解决方案3】:

    由于您的输入文件具有由空行分隔的架构,您可以在段落模式下使用 awk,然后它很简单:

    $ awk -v RS= '/hello/{++c} END{print c}' file
    3
    

    【讨论】:

    • 作为awk的新手,-v,RS=是什么?在 awk 的计划中 :) @ed-morton
    • -v 是设置 awk 变量的标志,RS 是记录分隔符,用于定义哪些字符/字符串/正则表达式分隔记录,RS= 或 RS="" 将 RS 设置为null char 告诉 awk 记录由空行分隔。
    • tnx!顺便说一句,你昨天提到的那本关于 awk 的书有 2014 年第 4.th 最新版,要说什么,比较我们的解决方案,你的字符更少,可读性更高。对于步行步行,骑自行车,足够了! (不需要汽车)
    猜你喜欢
    • 2023-03-13
    • 1970-01-01
    • 2022-01-11
    • 2017-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    相关资源
    最近更新 更多