sed帮助:如何仅当在另一个匹配行范围内找到时才打印一行范围



我有一些输入,您可能会将其识别为JSON流,我需要从一个简单的shell脚本中处理它

我选择了使用sed,因为我需要进行的六种其他操作已经可以很好地使用sed了。

下面是场景。

输入1:

{
"Expr": {
"Criteria": [
{
"Values": [
{
"displayValue": "MyObject",
"value": "UUID"
}
]
}
],
"Type": "SELECTED"
}
} 

预期结果1(打印包含displayValue+值对的子句[s](:

{
"displayValue": "MyObject",
"value": "UUID"
}

尝试:

$ sed -n -e '/"Expr":/,/"Type": "SELECTED"/ {/"Values":/,/^                    }$/ {/^                    {/,/^                    }/p;};}' /tmp/input1.json

实际结果(良好(:

{
"displayValue": "MyObject",
"value": "UUID"
}

此输入出现问题2:

{
"Expr": {
"Criteria": [
{
"Values": [
{
"displayValue": "MyObject",
"value": "UUID"
}
]
}
],
"Type": "NOT_SELECTED"
}
}

结果出乎意料(由于外部嵌套为NOT_SELECTED,除非SELECTED,否则不希望匹配(:

$ sed -n -e '/"Expr":/,/"Type": "SELECTED"/ {/"Values":/,/^                    }$/ {/^                    {/,/^                    }/p;};}' /tmp/input2.json

结果2:

{
"displayValue": "MyObject",
"value": "UUID"
}

是我,还是我平台上的sed bug?否则,你能提出一个解决这个问题的好方法吗?

约束条件是我不想打印";标准";不在";类型";是";选择的";范围

这可能对你有用(GNU sed(:

sed -En '/"Expr"/{:a;n;H;/"Values"/h;/"Type"/!ba;/"SELECTED"/!d;g;s/.*n((s*){.*2}).*/1/p}' file

使用循环而不是范围。

"Expr""Type"之间形成循环,并且只有当引用的单词"SELECTED"存在时才继续。

在执行循环时,将Values保存在保留空间中,然后操作保存的内容以仅显示所需的部分。

注意:这是一个筛选操作,因此请使用-n选项。

请记住,sed不会在文件中向前看。因此,多行技术必须用于此工作。我的方法是";"诋毁";顶层{}之间的行,我假设它们由一个字符组成({},没有前导和尾随空格(,并检查生成的模式空间:

sed '
/^{$/,/^}$/{
//!{H;d;}
g
s/.*"Values":.*(n[[:space:]]*{[^}]*"displayValue":[^}]*"value":[^}]*}).*"Type":[[:space:]]"SELECTED".*/1/p
s/.*//
h
d
}' file

最新更新