背景:我有一个配置文件,用于存储此格式的变体值:
(以下是使用虚构数据的示例)
'names': { "john", "jeff", "stewie", "amy", "emily" }
一些格式详情:
此列表中的元素可以按行而不是按行描述 空间。例如,这也是可以接受的:
'names': { "john",
"jeff",
"stewie",
"amy",
"emily"
}
这就是:
'names': { "john", "jeff", "stewie",
"amy", "emily" }
我正在尝试创建的功能:我想从名为“names”的列表中删除“amy”。
我一直在尝试使用sed创建此行为,但我愿意使用bash,awk,cut或其中的一些组合。
如果列表中的元素在一行上,这很容易:
/bin/sed -i "/names/ s/ ${element}//" $f
(其中$element
包含"amy"
,$f
包含我正在编辑的文件
但多线的可能性让我感到高兴。
思想?
答案 0 :(得分:2)
让我们考虑包含所有三种情况的输入文件:
$ cat file
'names': { "john", "jeff", "stewie", "amy", "emily" }
'names': { "john",
"jeff",
"stewie",
"amy",
"emily"
}
'names': { "john", "jeff", "stewie",
"amy", "emily" }
现在,让我们应用此sed
命令删除amy
:
$ sed '/names/{:a;/}/!{N;b a}; s/"amy",[[:space:]]*//}' file
'names': { "john", "jeff", "stewie", "emily" }
'names': { "john",
"jeff",
"stewie",
"emily"
}
'names': { "john", "jeff", "stewie",
"emily" }
/names/
任何时候一行包含names
,我们就会开始执行命令。其他行未更改。
:a; /}/! {N;b a}
一旦我们的行包含names
,我们会读到其他行,直到我们得到一个包含右括号的行。即使它分布在多行上,也会立即获得完整的names
分配。
更详细地说,:a
是一个标签。 /}/!
是一个条件。如果该行不包含}
,则执行语句N; b a
。 N
读取下一行并将其添加到模式空间。 b a
跳转(分支)回标签a
。因此,这种情况一直持续到从names
到}
的完整分配都在模式空间中。
s/"amy",[[:space:]]*//}
在sed的模式空间中完成names
分配后,我们会查找"amy",
以及后面的任何空格,我们将其删除。
上述解决方案假定逗号后跟名称amy
。但是,假设amy
可能是列表中的姓氏,如下文所示:
$ cat file
'names': { "john", "jeff", "stewie", "emily", "amy" }
'names': { "john",
"jeff",
"stewie",
"emily",
"amy"
}
'names': { "john", "jeff", "stewie",
"emily", "amy"}
要处理这种情况,我们需要添加一个替代命令:
$ sed '/names/{:a;/}/!{N;b a}; s/"amy",[[:space:]]*//; s/,[[:space:]]*"amy"//}' file
'names': { "john", "jeff", "stewie", "emily" }
'names': { "john",
"jeff",
"stewie",
"emily"
}
'names': { "john", "jeff", "stewie",
"emily"}
答案 1 :(得分:0)
使用sed如下:
sed -r ':loop;$!{N;b loop};s/(.names.: ?\{[^}]*)"amy",? *([^}]*\})/\1\2/g' my-file
答案 2 :(得分:0)
为什么不直接使用bash字符串处理例程:
http://tldp.org/LDP/abs/html/string-manipulation.html
stringZ=abcABC123ABCabc
echo ${stringZ/abc/xyz}
result = bcABC123ABCxyz
在你的情况下
export stringZ="\'names\': \{ \"john\", \"jeff\", \"stewie\", \"amy\", \"emily\" }"
echo ${stringZ/\"amy\",/}
返回'姓名':{“john”,“jeff”,“stewie”,“emily”}