【问题标题】:Search for a particular multiline pattern using awk and sed使用 awk 和 sed 搜索特定的多行模式
【发布时间】:2016-05-21 03:04:28
【问题描述】:

我想从文件/etc/lvm/lvm.conf 中读取并检查以下可能跨越多行的模式。

tags {
 hosttags = 1
} 

tags{{hosttags 之间可以有尽可能多的空格,以此类推。 { 也可以在下一行跟随 tags 而不是与它在同一行。

我打算使用awksed 来执行此操作。

在读取文件lvm.conf 时,它应该跳过空行和cmets。

我正在使用的。

data=$(awk < cat `cat /etc/lvm/lvm.conf`            
/^#/        { next }                       
/^[[:space:]]*#/            { next }                
/^[[:space:]]*$/            { next }                
.          
.                            

如何使用sed 找到我上面描述的模式?

【问题讨论】:

    标签: sed awk


    【解决方案1】:

    你在找这样的东西吗

    sed -n '/{/,/}/p' input
    

    即标记之间的打印行(包括)?

    要删除包含# 的行和空行或仅包含空格的行,请使用

    sed -n '/{/,/}/p' input | sed '/#/d' | sed '/^[  ]*$/d'
    
                                  space and a tab--^
    

    更新

    如果空行只是空行(没有ws),上面可以缩短为

    sed -e '/#/d' -e '/^$/d' input
    

    更新2

    要检查模式 tags {... 是否存在于文件中,请使用

    $ tr -d '\n' < input | grep -o 'tags\s*{[^}]*}'
    tags { hosttags = 1# this is a comment}
    

    上面的 tr 部分删除了所有换行符,即将所有内容都放在一行中(如果文件不是很大,则效果很好),然后搜索 tags 模式并输出所有匹配项。

    如果找到了模式,则 grep 的返回码将为 0,否则为 1。 返回代码存储在变量$? 中。或者通过管道将上述内容发送到wc -l 以获取找到的匹配数。

    更新3

    用于搜索tags { hosttags=1 } 的正则表达式,在任何地方使用任意数量的ws

    'tags\s*{\s*hosttags\s*=\s*1*[^}]*}'
    

    【讨论】:

    • 看来 op 想跳过 cmets
    • 这很好用 sed '/#/d' | sed '/^[ ]*$/d' .. 但我想要的是搜索模式.. 不只是打印它.. 另请注意,模式之间可以有空格..
    • @user2161443 - 您需要一种方法来判断 tags { ... } 是否在文件中?
    • @FredrikPihl .. 是的,我想检查 lvm.conf 文件中是否存在模式标签 { hosttage = 0 }
    • @FredrikPihl,更新后的命令有效。但它不搜索主机标签。我需要整个东西标签 { hostname = 1 } 并且模式之间可以有很多空格..我认为 'tags\s*{[^}]*}' 需要一些修改..请建议
    【解决方案2】:

    试试这条线:

     awk '/^\s*#|^\s*$/{next}1' /etc/lvm/lvm.conf
    

    【讨论】:

    • 看起来不错,但是只显示括号之间的模式呢?
    • @FredrikPihl 为什么?没有这些信息,就无法理解 conf 文件。 OP也没有要求...
    • 是的。我的主要目的是检查模式是否存在于 lvm.conf 文件中。
    • @FredrikPihl 从技术上讲,它可以通过两种肮脏的方式(也许更多)方式来完成。 1)又脏又快的A匹配{}然后next 2)又脏又快的B,让RS匹配..{.. or ..}..
    【解决方案3】:

    可以尝试先对文件进行预处理,删除注释和空行,并在右花括号后面引入空行,以便使用第二个 awk 进行处理。

    awk 'NF && $1!~/^#/{print; if(/}/) print x}' file | awk '/pattern/' RS=
    

    【讨论】:

      猜你喜欢
      • 2017-10-19
      • 1970-01-01
      • 2015-02-24
      • 2017-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-10
      相关资源
      最近更新 更多