Я использую команду sed чтобы изменить <active>true на <active>false в файле XML. Теперь, если я использую

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

это полностью стирает содержимое моего файла. Используя >> вместо > , он добавляет вывод в конце, как и ожидалось.

  1. Как добиться того, что я хочу сделать?
  2. Почему > ведет себя так странно?
  3. Что я на самом деле хочу сделать, так это изменить <active>true на <active>false если <active>true присутствует, и наоборот, если <active>false присутствует в файле. Есть какая-то команда, которая может это сделать, или мне нужно написать сценарий с if-else как мой первоначальный план?

1 ответ1

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 . Это приводит к тому, что каждое совпадение true или false заканчивается как true . По этой причине я использовал временную замену DUMMY . Может быть, есть лучший способ сделать это, я пока не знаю.

Единственное условие - строка <active>DUMMY не может появиться в исходном файле. Если это может появиться, используйте другую фиктивную строку, которая точно не появляется.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .