我正在尝试使用-
替换JSON文件的密钥名称中的连字符_
,而不会影响键值对的值侧。
示例输入:
{
"outcome": "failed",
"failure-description": "ra ra ra - and more",
"rolled-back": true
}
有没有办法用sed做到这一点?它可能是匹配模式,其中sed只会在"(.*[^"])":
之间替换,但我无法找到如何替换匹配子字符串中不需要的字符。
预期结果如下:
{
"outcome": "failed",
"failure_description": "ra ra ra - and more",
"rolled_back": true
}
答案 0 :(得分:0)
这样可行:
$ sed 's/-\([^:]*\):/_\1:/' infile
{
"outcome": "failed",
"failure_description": "ra ra ra - and more",
"rolled_back": true
}
这会查找-
后跟捕获的除冒号之外的一系列字符,然后是冒号;它用下划线替换连字符,并将捕获的组和冒号放回去。
这个限制是它只替换第一个连字符。假设我们的输入如下:
{
"outcome": "failed",
"failure-description": "ra ra ra - and more",
"two-hyphens-here": "ra ra ra - and more",
"rolled-back": true
}
要在冒号之前替换所有连字符,我们可以使用条件分支:
$ sed ':a;s/-\([^:]*\):/_\1:/;ta' infile
{
"outcome": "failed",
"failure_description": "ra ra ra - and more",
"two_hyphens_here": "ra ra ra - and more",
"rolled_back": true
}
设置标签(:a
)并使用t
命令(如果模式空间已更改,则分支标记)。
对于在Mac OS中找到的BSD sed,标签必须在单独的命令中:
sed -e ':a' -e 's/-\([^:]*\):/_\1:/;ta' infile
请注意,所有这些的固有限制是引号之间不能有任何冒号,并且通常建议使用适当的JSON解析器(如jq)来执行此类操作。
答案 1 :(得分:0)
使用扩展的正则表达式和括号结构。
-r, --regexp-extended
use extended regular expressions in the script.
这会产生正确的结果,但可能需要进行一些调整以强化正则表达式以防止错误匹配:
sed -re 's/([:alpha:]*)[-]([:alpha:]*)/\1_\2/'
结果:
{
"outcome": "failed",
"failure_description": "ra ra ra - and more",
"rolled_back": true
}
注意,如果值侧包含模式,则上面给出的简单表达式是不合适的。检查您的数据集,根据需要添加更多带括号的表达式和对它们的引用,以更紧密地锚定匹配。可以嵌套带括号的表达式,但这确实会使确定对它的后向引用变得复杂。
$ sed --version
GNU sed version 4.1.5
答案 2 :(得分:0)
只需使用awk:
$ awk 'BEGIN{FS=OFS="\": \""} {gsub(/-/,"_",$1)} 1' file
{
"outcome": "failed",
"failure_description": "ra ra ra - and more",
"rolled_back": true
}