Разбор XML с помощью сценария оболочки

Я использую xmlstarlet в сценарии оболочки для анализа XML-файла без названия app.xml с помощью этой команды, просто чтобы получить содержимое, которое является строкой, и сохранить его в «my_var»:

my_var=`xmlstarlet sel -t -m "//root/services/service[position=$i]" -v description -n /home/wissem/Bureau/app.xml`

затем при попытке изменить другой XML-файл без названия strings.xml с выводом последней команды, используя эту командную строку:

find /root/AndroidStudioProjects/FacebookMenu/app/src/main/res/values/strings.xml -type f -exec  perl -pi -w -e 's/name=\"text_'$i'\".*\<\/string\>/name=\"text_'$i'\"\>'$my_var'\<\/string\>/g' {} \;

я получаю следующую ошибку:

Substitution replacement not terminated at -e line 1.

я попытался понять проблему, по отдельности изменив строку, которую я анализирую, в свою переменную, я заметил, что проблема возникает, когда у меня есть «пробел» в строке!

чтобы объяснить больше :for this_is_my_string : это работает

для этого моя строка: я получаю сообщение об ошибке.


person wissem46    schedule 02.04.2014    source источник


Ответы (1)


Да, если $my_var содержит пробелы, оболочка разобьет аргументы в $my_var. Это должно работать:

-e "s;name=\"text_$i\".*</string>;name=\"text_$i\">$my_var</string>;g"

Двойные кавычки предотвращают разделение вашего аргумента. Двойные кавычки, которые вы хотите использовать в своем аргументе, были уже заключены в кавычки с обратной косой чертой, что защищает их. И $ переменные расширяются при заключении в двойные кавычки. Я также заменил s/../../g на s;...;...;g, чтобы косая черта не нуждалась в экранировании. И я почти уверен, что нет причин избегать угловых скобок.

Я проверил вышеизложенное с помощью этой процедуры:

  1. Создайте /tmp/testq.xml, содержащий:

    <string name="text_100">Blah</string>
    
  2. Проблема:

    i=100
    my_var="room service"
    
  3. Проблема:

    find /tmp/ -name "testq.xml" -exec perl -p -e "s;name=\"text_$i\".*</string>;name=\"text_$i\">$my_var</string>;g" '{}' \;
    
  4. Результат на стандартный вывод:

    <string name="text_100">room service</string>
    

Я не использую -i в приведенном выше тесте, потому что хочу иметь возможность повторно запускать тест любое количество раз, но -i не должно влиять на достоверность выражения -e.

person Louis    schedule 02.04.2014