如何使用 `sed` 来交换两个模式?

如何使用 `sed` 来交换两个模式?

我正在使用命令在 xml 文件中sed更改<active>true为。现在如果我使用<active>false

sed 's/<active>true/<active>false/g' file.xml > file.xml

它完全删除了我的文件内容。使用>>而不是 时>,它会像预期的那样在末尾附加输出。

  1. 怎样才能实现我想要做的事?
  2. 为何>行为如此怪异?
  3. 我实际上想要做的是将if存在 更改<active>true为if 存在,反之亦然。是否有一些命令可以做到这一点,还是我需要像我最初的计划那样编写一个脚本?<active>false<active>true<active>falseif-else

答案1

的行为>解释为这个 Unix 和 Linux SE 答案。那里有例子cat test.txt > test.txt,解释如下:

首先发生的事情是 bash 打开了test.txt,它截断了文件。现在它是空的,然后才以为参数cat执行。test.txt

您的sed '…' file.xml > file.xml触发器会触发相同的行为。

非常简单的解决方案,只需一个sed

sed -i 's/<active>true/<active>DUMMY/g
   s/<active>false/<active>true/g
   s/<active>DUMMY/<active>false/g' file.xml

-i选项解决了文件被截断的问题。该命令变为<active>true<active>false反之亦然。请注意,您不能只使用

s/<active>true/<active>false/g;s/<active>false/<active>true/g

因为第二部分无法判断是否有任何false原始的false或原始的true只是变成了false。这导致每个匹配的truefalse最终都变成true。为此我使用了临时DUMMY替换。也许有更好的方法,我还不知道。

唯一的条件是该字符串<active>DUMMY不能出现在原始文件中。如果可能出现,请使用另一个肯定不会出现的虚拟字符串。

相关内容