Следующий синтаксис используется для захвата слова между <Name> в .xml файле. Я также использую xargs для удаления пробелов.

$> var=` find /tmp -name '*.xml' -exec sed -n 's/<Name>\([^<]*\)<\/Name>/\1/p' {} +  |  xargs `
$> echo $var
TOPIC
$>

До сих пор, кажется, все в порядке. Но printf показывает что-то еще:

$> printf "%q\n" "$var"
$'TOPIC\r'
$>

Давайте углубимся в:

$> [[ TOPIC == $var ]] && echo they are equal
$>

Никаких "они равны" никогда не печатали.

Но когда мы выводим $var мы получаем:

$> echo $var
TOPIC
$>

БОЛЬШОЙ БОЛЬШОЙ вопрос: как удалить лишние символы ($ , \r) из переменной?

$'TOPIC\r'

1 ответ1

1

$ не находится ни в переменной, ни в литерале \r . Они добавляются в вывод, потому что вы сказали printf форматировать следующим образом: %q . Настоящий дополнительный символ - "возврат каретки", код 0x0D , escape-последовательность которого равна \r .

Корень вашей проблемы в том, что ваши .xml файлы, похоже, используют окончания строк CR+LF из мира DOS/Windows. Смотрите это сравнение в Википедии.

В документе Extensible Markup Language (XML) 1.0 (пятое издание) говорится:

Чтобы упростить задачи приложений, процессор XML должен вести себя так, как будто он нормализует все разрывы строк во внешних проанализированных объектах (включая объект документа) при вводе перед синтаксическим анализом путем перевода двухсимвольной последовательности #xD #xA и любого #xD , за которым не следует #xA до одного #xA .

Здесь #xD обозначает CR, #xA обозначает LF.

В вашем случае вся find … | xargs заявление процессор XML (давайте такие проблемы , как это в сторону). Если вы хотите полностью соответствовать спецификации, вы должны пропустить каждый файл .xml через dos2unix с самого начала.

Но поскольку настоящая проблема связана с содержимым переменной, в вашем случае этого может быть достаточно:

var=`find … | dos2unix | xargs`

Если у вас нет dos2unix , tr -d '\r' будет работать в качестве замены в этом контексте (спасибо @GordonDavisson за это).

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