Строковая замена в файле

Ну, я собирался сказать, делают это сценарием, потому что псевдонимы действительно не предназначены, чтобы сделать, сложные вещи как это и сценарии предназначены для более - сложные или более длинные выполняющиеся задачи. Псевдонимы в основном предназначены, чтобы отобразить одну команду на другого, например, предоставить параметры по умолчанию команде, которая не поддерживает это исходно.

Однако, так как Вы заявили в комментарии, что Вы хотите сохранить это псевдонимом, мы должны будем выяснить, как сделать то, что Вы хотите в границах псевдонима.

Естественный выбор затем становится для запуска подоболочки из псевдонима. Например:

~$ alias xyz1='( cd ~/tmp; sleep 10; cd ~ )'
~$ alias xyz2='cd ~/tmp; sleep 10; cd ~'
~$ xyz2
^C
~/tmp$ cd
~$ xyz1
^C
~$

Это изменяет рабочий каталог только в подоболочке, которая выходит, когда или псевдоним заканчивает выполняться обычно или прерывается, например, через Ctrl+C.

3
01.07.2014, 14:26
3 ответа

С недавним (для \K и s///r) perl и предполагая, что ваши метки не гнездятся:

perl -0777 -pi.bak -e's{<string.*?>\K.*?(?=</string>)}{$&=~s/-/&#8211;/rg}ges' file.xml
  • -0777: slurp mode: обрабатывать весь файл сразу (чтобы теги могли занимать несколько строк).
  • -p: sed mode
  • -i.bak: редактирование на месте с расширением .bak (BTW, именно оттуда некоторые реализации sed получили эту идею)
  • s{...}{..... }ges: замена глобально (g), где . также совпадает с символами новой строки (s), и рассматривает замену как код perl для выполнения (e).
  • \K.*? : совпадает с до , но не включайте сами теги в ту часть, которая соответствует (\K определяет, где начинается соответствует порция, и (? =...) является оператором поиска, который только проверяет, если есть, но не включает его в соответствие).
  • $&=~s/.../.../rg. Соответствует ли подстановка в части ($&). Флаг r на самом деле не изменять $&, а возвращать подставленную строку.
3
27.01.2020, 21:11

Если я правильно понял, вы хотите заменить все случаи (три в вашем примере) - в тегах и только эти случаи. Если это так, то эти подходы должны работать в предположении, что ваш XML вменяем:

  1. Используйте регулярное выражение и простой инструмент типа sed

    sed 's/\(]*>[^-]*\)-\([^-]*<\/string\)/\1\–\2/' file.xml. 
    
  2. Если ваш файл всегда, как в примере выше, и вы можете быть уверены, что ваши теги всегда будут <имя строки="test" >, вы можете использовать lookbehinds:

    perl-pe 's/(? <=)([^<]*?)-([^<]*)/$1–$2/g' file.xml
    
  3. Ни одно из вышеперечисленного не сработает, если в тегах будет более одного -. Чтобы справиться с такими случаями, можно написать простой маленький скрипт, который проверяет, находимся ли мы внутри тегов . Это также должно касаться вложенных тегов.

    perl -F'<' -lane 'for($i=0;$i<=$#F;$i++){
     $a++ если $F[$i]=~/^string/; 
     $F[$i]=~s/-/–/g if $a>0; 
     $a-- если $F[$i]=~/^\/string/
    } распечатайте join "<",@F' file.xml
    
2
27.01.2020, 21:11

Уф, через какое-то время я понял. Это наивное решение. ответ Тердона более правильный и вы должны использовать его хотя :).

sed -Ei.bak "s/(.*<string[^>]*\")(.*)-(.*)/\1\2\&#8211;\3/g" strings.xml

Я использую Обратные ссылки , чтобы вернуться к ранее сопоставленной строке. Это \ 1 \ 2 и т. Д.

В этом случае sed должен соответствовать следующим группам:

  • (. * ] * \ ") - любой символы, за которыми следует строковый тег, открывающийся до кавычки ". Группа 1
  • (. *) - все, что находится после " (включая прямо сейчас > ) до группы 3. Группа 2
  • - соответствующий тире
  • (. *) - все, что находится после совпадающего тире Группа 3

Затем я заменяю его ранее сопоставленными группами и значением HTML тире - , используя \ n с n в качестве ссылки на группу n .

Проблемы:

В настоящее время я пытаюсь исправить некоторые проблемы, так что, пожалуйста, справьтесь со мной:

  1. Группа 1 также соответствует dsfjpasj
  2. Группа 1 должна включать символ окончания строкового тега >
  3. Как указывает Тердон: «это не сработает для случаи, когда у вас есть > 1 - или вложенные теги или теги, занимающие несколько строк »

Подробнее:

http://toytoygogie.blogspot.de/2010/02/using-sed-with -backreference-as.html

3
27.01.2020, 21:11

Теги

Похожие вопросы