bash – sed:如果匹配模式,则打印分隔的行块
我想使用sed来匹配由pattern1 / pattern2分隔的行块,然后仅在包含pattern3的块上执行操作(例如,打印块).
在下面的示例中,我正在寻找“抓住我,如果可以的话”,在由匹配{和}的行分隔的所有块中(然后我想要完整地打印匹配的块). 我尝试过的: sed -n -e '/{/,/}/{1h;1!{$!{H;d};H;x;/catch me if you can/p}}' (想法是匹配由{和}分隔的块,然后将每个块累积到保留空间;在每个块的末尾,交换保持空间并执行匹配以“抓住我,如果可以的话”). 输入数据: "block1": { "foo": "abcd","bar": "catch me if you can","aaa": "12345" },"block2": { "bbb": "24680","bar": "blah","foo": "argh","ccc": "135" },"block3": { "ddd": "zzz" },"block4": { "foo": "xyz",} 期望的输出: "block1": { "foo": "abcd","bar": "catch me if you can" }, 注1:每个块内的字段顺序是随机的.字段数和值的长度在块之间不是恒定的.我正在寻找的字段可能在某些块中丢失(而不是仅具有不同的值). 注2:出于教育目的,我更喜欢使用sed的解决方案,但如果不可能,awk或bash也可以.请不要使用perl或其他工具. 参考文献: > Sed command summary 解决方法
我就是这样做的.这里有两个版本,一个用于BSD(Mac OS X)sed(也适用于其他未运行GNU sed的系统),另一个用于GNU sed.
BSD sed $cat script.bsd-sed /{/,/}/{ /{/{ h; b next } /}/{ H; x; /catch me if you can/p; b next } H :next } $sed -n -f script.bsd-sed data "block1": { "foo": "abcd",} $ 逻辑是: >除非被告知这样做(-n),否则不要打印任何内容. BSD(经典)sed在b next之后的行上不需要任何内容??,因此动作的}在下一行. GNU sed $cat script.gnu-sed /{/,/}/{ /{/{ h; b next } /}/{ H; x; /catch me if you can/p; b next } H :next } $/opt/gnu/bin/sed -n -f script.gnu-sed data "block1": { "foo": "abcd",} $ GNU sed在标签终止命令后识别分号或闭括号,因此它允许更紧凑的表示法.你甚至可以将它们整合成一行 – 你必须添加几个分号: $/opt/gnu/bin/sed -n -e '/{/,/}/{ /{/{ h; b next }; /}/{ H; x; /catch me if you can/p; b next }; H; :next }' data "block1": { "foo": "abcd",} $ 您也可以删除不在模式匹配中的空格: $/opt/gnu/bin/sed -n -e '/{/,/}/{/{/{ h;b next};/}/{H;x;/catch me if you can/p;b next};H;:next}' data "block1": { "foo": "abcd",} $ 扩展数据文件数据 "block1": { "foo": "abcd",} "block5": [ "oops": "catch me if you can" ],"block6": { "rhubarb": "dandelion" } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |