我正在使用几周前更新的 Arch。包是使用是
- 拱门 6.0.10-arch2-1
- BASH 5.1.16(1)-发布
- gnu sed 4.9
- gnu grep 3.8
- 打开盒子 3.6.1
在我的 Openboxrc.xml
文本文件中,我有两行如下
<!-- <keybind key="Right"> -->
<keybind key="s-Up">
我希望使用脚本经常将上面两行切换/交换为下面两行
<!-- <keybind key="s-Up"> -->
<keybind key="Right">
rc.xml
这使我能够快速更改键绑定,而无需每次都繁琐地编辑我的键绑定设置文本文件 ( )。
到目前为止,我的脚本在下面,但无法正常工作,尽管我知道它很接近。
我不太在意这种切换是如何实现的,但是已经花了很多时间在这上面,让下面的脚本工作会很好。
下面的sed
表达式按预期进行文本交换。
如果满足条件,该if
语句似乎会进行第一次sed
交换,但如果不满足条件,则不会进行第二次sed
交换,这就是问题所在。
var_a=""
#var_a=$(grep -zoP "<\!\-\- <keybind key=\"Right\"> \-\->\n\n<keybind key=\"s-Up\">" /home/kes/Dropbox/lubuntu-rc.xml | sed ':a;N;$!ba;s|\n\n||g')
var_a=$(grep -zoP "<\!\-\- <keybind key=\"Right\"> \-\->\n\n<keybind key=\"s-Up\">" /home/kes/Dropbox/lubuntu-rc.xml | tr -d '\n' )
# result of grep is
# <!-- <keybind key="Right"> --><keybind key="s-Up">
echo $var_a; sleep 0.5
#if [[ -z ! "$var_a" ];then
if [[ '$var_a'=='<!-- <keybind key="Right"> --><keybind key="s-Up">' ]]; then
sed -ie ':a;N;$!ba;s|<!-- <keybind key="Right"> -->\n\n<keybind key="s-Up">|<!-- <keybind key="s-Up"> -->\n\n<keybind key="Right">|g' /home/kes/Dropbox/lubuntu-rc.xml
else
sed -ie ':a;N;$!ba;s|<!-- <keybind key="s-Up"> -->\n\n<keybind key="Right">|<!-- <keybind key="Right"> -->\n\n<keybind key="s-Up">|g' /home/kes/Dropbox/lubuntu-rc.xml
fi
实际上,永远不会满足条件,因为单引号
'$var_a'
会阻止您的变量完全展开,因此文字字符串$var_a
永远不会等于其他文字字符串。使用双引号,它应该可以工作,但我想对您的脚本添加一些评论:
(1)你首先做一个
grep
,然后基于你从中得到的内容的条件grep
,最后使用两个不同的sed
脚本。这很可能会导致错误。实际上,您sed
将独自完成整件事:如果进行了第一个替换,则
t
跳转到脚本末尾,否则执行另一个替换。和已经包含在内grep
!if
(2)你收集所有行的方法
:a;N;$!ba
只适用于 GNUsed
,因为根据 POSIX 标准,冒号后的所有内容都是跳转标记,也不例外;
。对你来说没问题,因为你有 GNUsed
,但你也可以-z
选择在没有零件的情况下一次运行处理孔文件。如果你喜欢它便携,H;1h;$!d;x
通过保持空间做同样的事情。(3)我认为,
g
lobal 标志是多余的,因为那些线只存在一次,对吗?(4)一遍又一遍地写同样的东西,可能会导致错误并且更难阅读。为什么不通过标记
\(\)
并引用它来重用一个零件\1
呢?(5)其实不需要把整个文件当成一个文件来处理(对于大文件甚至会造成溢出),只需要将连续的每三行一起处理,使用
N;P;D
scheme(一般是两行一起,添加1N
到将其扩展为三行):人们可能会进一步简化这一过程,但这需要有关文件内容的额外信息。
假设 XML 文档格式正确且句法正确,您可以使用 XML 处理器
xmlstarlet
来切换值。忽略文档中注释掉的 XML,下面通过首先将每个节点的所有
key
属性从值更改为(具有其他值的属性不会受到影响)来实现此目的。然后它将相同的属性从更改为,最后从更改为。该字符串是一个任意字符串,否则不用于节点的属性。keybind
Right
temporary
s-Up
Right
temporary
s-Up
temporary
key
keybind
这有效地交换了从
Right
到的值,s-Up
反之亦然。这将把一个文件变成像
... 进入
如果
--inplace
直接在edit
命令行中的单词后插入,编辑将就地进行,修改原始文件。