Переменная выдает ожидаемое значение, но на самом деле его значение отличается

237
enodmilvado

Следующий синтаксис используется для того, чтобы перехватить слово между <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' 
0

1 ответ на вопрос

1
Kamil Maciorowski

$не в переменной, ни в буквальном \r. Они добавляются к выходу, потому что вы сказали, printfформатировать следующим образом: %q. Реальный дополнительный символ «возврат каретки», код 0x0D, который управляющая последовательностью является \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 за указание на это).

Если у вас нет `dos2unix`,` tr -d '\ r'` будет работать в качестве замены в этом контексте. Gordon Davisson 6 лет назад 1
@GordonDavisson Спасибо, это полезно. Kamil Maciorowski 6 лет назад 0

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