我正在使用Linux。我有一个yml文件,我想用sed删除它:
exposureMachineSshAccess
username:
password:
whiteList:
- mLB99
- mLB10
machines:
- machineId:
username: ''
password: ''
- machineId:
username: ''
password: ''
我已经创建了这个正则表达式,看起来没问题:
exposureMachineSshAccess:\n([ ].*\n)+
我在说这个:
sed -i '/exposureMachineSshAccess:\n([ ].*\n)+/d' /home/common_config.yml
sed -i 's/exposureMachineSshAccess:/d/gm' /home/common_config.yml
如果我删除正则表达式,我将文件更改,但它不起作用。有什么问题?
答案 0 :(得分:4)
你的正则表达式不起作用的原因是sed
一次检查一行。您希望删除起始地址为exposureMachineSshAccess
行且结尾为password:
行的地址范围内的行。
sed -i '/exposureMachineSshAccess/,/ password:/d' common_config.yml
这仍然是不精确的,因为它要求密码行是此YAML记录中的最后一行。如果记录之间有空行,请将其用作结束地址。如果你有可靠的缩进,可能会停在下一行与左边距齐平的行(但这需要对脚本进行一些重构,以便不删除范围末尾的行)。
正确的解决方案是使用能够正确理解YAML的工具。我提出了这个问题的副本,它有一些模糊的短片段,可能比口香糖和胶带方法更精确,更健壮,也就是说,试图用正则表达式处理结构化文件格式。
答案 1 :(得分:2)
使用tac
和sed
的解决方案:如果您不想这样做,将会删除Input_file中最后一次出现的字符串password:
,然后解决方案2可以帮助您相同的:
tac Input_file | sed "/ password: ''/,/exposureMachineSshAccess/d" | tac
假设以下是Input_file:
cat Input_file
exposureMachineSshAccess
username:
password:
whiteList:
- mLB99
- mLB10
machines:
- machineId:
username: ''
password: ''
- machineId:
username: ''
password: ''
singh is king ......
test1221
然后运行上面的代码后输出如下:
tac Input_file | sed "/ password: ''/,/exposureMachineSshAccess/d" | tac
testtest1221 test
singh is king ......
test1221
解决方案第二:
sed "/exposureMachineSshAccess/,/ password: ''/d" Input_file
答案 2 :(得分:2)
这可能适合你(GNU sed):
sed '/^\S/h;G;/\nexposureMachineSshAccess/!P;d' file
这会复制节标题。将节标题追加到每一行,并根据节标题匹配打印/删除。