Я имею ниже команды для нахождения весь .xml
файлы, содержащие <active>true</active>
наличие <codePool>community</codePool>
после той строки на следующей строке.
grep -rzl '<active>true</active>.*<codePool>community</codePool>' --include='*.xml' --color=always
Теперь, как объединить это с sed
заменять true
представьте в виде строки в <active>...
тег к false
обмануть тем подобранным строкам?
Спасибо за ответ @glennjackman, я был также успешным достижением моего требования со следующим кодом, это уязвимо, упаковывают входные изменения, но это будет последовательное хранение фиксированной структуры каталогов и формата файла XML-файлов Magento в памяти:
for filename in *.xml; do
if grep -q '<codePool>community</codePool>' "$filename"; then
if [[ $filename != *"Mage_"* ]]; then
sed -i.bak 's/<active>true<\/active>/<active>false<\/active>/g' "$filename"
fi
fi
done
Этот способ, которым я также смог скопировать те файлы сначала, которые были измененными, просто способ, которым я хотел.
Hope это упрощает вещи и перенаправляет всех/целых возможных людей к пользованию внутренними библиотеками вместо того, чтобы установить сторонние инструменты, которым не позволяют установить в сетях Remote SSH/VPN.
Необходимо использовать XML парсинг инструментов для данных XML. xmlstarlet
хороший выбор. Регулярные выражения просто не достаточно мощны (каноническая ссылка)
Если Ваши данные похожи:
<root>
<foo>
<active>true</active>
<codePool>private</codePool>
</foo>
<foo>
<active>true</active>
<codePool>community</codePool>
</foo>
</root>
Затем
xmlstarlet ed --update '//active[.="true" and ../codePool="community"]' -v false file.xml
производит
<?xml version="1.0"?>
<root>
<foo>
<active>true</active>
<codePool>private</codePool>
</foo>
<foo>
<active>false</active>
<codePool>community</codePool>
</foo>
</root>
Вот awk программа, которая делает то, что Вы запрашиваете. Следует иметь в виду, что это хрупко: если вход изменится, то этот код прекратит работать. Это действительно просто использует простые строковые операции.
awk '
BEGIN {
marker = "<codePool>community</codePool>"
srch = "<active>true</active>"
repl = "<active>false</active>"
}
index($0, marker) {
i = index(prev, srch)
if (i > 0)
prev = substr(prev, 1, i-1) repl substr(prev, i+length(srch))
}
{
if (prev) print prev
prev = $0
}
END {if (prev) print prev}
'