Как сопоставить и заменить значение атрибута внутри тега

Я пытаюсь заменить значение следующего узла, используя команду sed.

<KeyValue key="EMPTY_SEARCH_CRITERIA" type="String" value="CS_CODE" comment="Configured empty search criteria."/> 

Я использую wildcard, поскольку начальное значение может содержать любое строковое значение. Напр.

 sed -e 's/value=.*/value="SN_CODE,CS_ID" comment="Configured empty search criteria."\/\>/g' CMS_conf.xml > tempfile ^ ^ ^ 

Но тогда, в этом случае, я должен также включить атрибут комментария.

Есть ли способ сделать это без ввода атрибута комментария?

Я бы использовал perl-диалект регулярных выражений. Если вы находитесь в системе с sed , тогда у вас, вероятно, будет perl.

Данный

 <KeyValue key="EMPTY_SEARCH_CRITERIA" type="String" value="CS_CODE" comment="Configured empty search criteria."/> 

Perl Regex

 perl -i -pe 's/(value=)".*?"/\1"some_replacement_string"/g' <filename> 

Заметки

Вы можете протестировать это сначала, сначала распечатав на терминал.

 perl -pe 's/(value=)".*?"/\1"some_replacement_string"/g' <filename> 

Или создайте резервную копию с расширением .bak

 perl -i.bak -pe 's/(value=)".*?"/\1"some_replacement_string"/g' <filename> 

Регулярное выражение:

  • (): group as variable \ 1
  • ": цитаты являются буквальными из-за единственного цитируемого выражения, поэтому нет необходимости их избегать.
  • ?: служит для приручения *, что означает, что он перестанет собираться в первом матче (и не будет продолжать жужжать до финала). sed не поддерживает неживых операторов, но вы можете использовать трюк в другом ответе [^"]*" , что означает« сожрать все символы вверх », которые не« до тех пор, пока ». Это фактически делает то же самое в этом случае.

Если вам особенно нужно изменить CS_CODE с помощью SN_CODE, CS_ID, вы можете использовать:

 's/CS_CODE/SN_CODE,CS_ID/g' 

Если значения отличаются, вы можете использовать

 's/value=\S*\S/value="SN_CODE,CS_ID"/g' 

sed – не самый яркий выбор для обработки html (или любого другого языка программирования), но так или иначе:

 sed -e 's/\(value\)="[^"]*"/\1="SN_CODE,CS_ID"/' 

Два, возможно, не очевидные точки:

  • с \( и \) мы группируем шаблон, чтобы использовать его позже с \1
  • [^"]* используется для соответствия любому символу, но "