我知道如何替换字符串;例如,在文件中将连字符替换为下划线。
但是,我希望将给定文件中尖括号内的所有文本的所有连字符替换为下划线。
例如,以下文件:
<charset-params>
<input-charset>
<resource-path>/*</resource-path>
<java-charset-name>UTF-8</java-charset-name>
</input-charset>
</charset-params>
应更改为:
<charset_params>
<input_charset>
<resource_path>/*</resource_path>
<java_charset_name>UTF-8</java_charset_name>
</input_charset>
</charset_params>
请注意,它UTF-8
没有改变,因为它不在尖括号内。我怎样才能做到这一点?
答案1
做
sed ': loop; s/\(<[^>]*\)-\([^>]*>\)/\1_\2/g; t loop'
查找s/\(<[^>]*\)-\([^>]*>\)/\1_\2/g
a <
、一堆(零个或多个)不是 的字符>
、一个连字符 ( -
)、另一堆不是 的字符>
,最后是 a >
。它将替换为-
、之前的部分_
以及 之后的部分-
。该g
运算符将使其一次执行多个替换,但它一次只能执行一个<
…… 。>
所以,举例来说,
<the-quick><brown-fox> <jumps-over> upside-down <the-lazy-dog>
将更改为
<the_quick><brown_fox> <jumps_over> upside-down <the-lazy_dog>
请注意,只有每个包含连字符的<
...>
单词发生了变化,但具有两个连字符 ( ) 的单词<the-lazy-dog>
仅更改了第二个 -
。上面t loop
说,如果进行了任何替换,请返回并尝试找到更多替换。
答案2
使用 perl 更容易:
perl -pe 's{<.*?>}{$& =~ y/-/_/r}ge' < your-file
或者:
perl -i -pe 's{<.*?>}{$& =~ y/-/_/r}ge' your-file
i
多处编辑文件。
答案3
在文件中使用您的示例:
<charset-params>
<input-charset>
<resource-path>/*</resource-path>
<java-charset-name>UTF-8</java-charset-name>
</input-charset>
</charset-params>
下面的 awk 将按以下方式完成工作,它将把“>”解释为要处理的节的结尾,并使用“<”作为节的开头,因此节内不考虑什么将被保存在数组部分中,之后该节内的所有内容都将被处理为所需的 gsub 替换,之后脚本必须恢复处理范围之外的分隔符和内容:
awk ' {numrec=split($0,regs,">")
for (i=1; i<numrec; ++i){
split(regs[i],part,"<")
gsub("-","_",part[2])
res = sprintf("%s%s",res, part[1] "<" part[2] ">")}
print res
res=""}' entraunder
结果如下:
<charset_params>
<input_charset>
<resource_path>/*</resource_path>
<java_charset_name>UTF-8</java_charset_name>
</input_charset>
</charset_params>
华泰
答案4
使用xq
它是一个命令行 XML 解析器,它是yq
工具包的一部分https://kislyuk.github.io/yq/(这是众所周知的 JSON 解析器的包装器jq
):
xq -x '
walk(
if type == "object" then
with_entries(.key |= gsub("-"; "_"))
else
.
end
)' file.xml
这会递归地遍历给定 XML 文件的整个结构,并且如果当前事物是一个对象,它将用下划线替换该对象中找到的所有键中的所有破折号。
例子:
$ cat file.xml
<charset-params>
<input-charset>
<resource-path>/*</resource-path>
<java-charset-name>UTF-8</java-charset-name>
</input-charset>
<something/>
</charset-params>
$ xq -x 'walk(if type == "object" then with_entries(.key|=gsub("-";"_")) else . end)' file.xml
<charset_params>
<input_charset>
<resource_path>/*</resource_path>
<java_charset_name>UTF-8</java_charset_name>
</input_charset>
<something></something>
</charset_params>
该工具可以使用或选项xq
执行就地编辑。-i
--in-place