我有一些输入,您可能会将其识别为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