Variable druckte den erwarteten Wert, aber tatsächlich ist der Wert unterschiedlich

341
enodmilvado

Die folgende Syntax wird verwendet, um das Wort dazwischen <Name>in der .xmlDatei zu erfassen . Ich verwende auch xargs, um Leerzeichen zu entfernen.

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

Bis jetzt scheint es in Ordnung zu sein. Aber printfzeigt etwas anderes:

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

Lassen Sie uns einen Drilldown machen:

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

Kein "sie sind gleich" jemals gedruckt.

Aber wenn wir uns wiederholen $var, bekommen wir:

$> echo $var TOPIC $> 

Die große Frage ist: Wie entferne ich die zusätzlichen Zeichen ( $, \r) aus der Variablen?

$'TOPIC\r' 
0

1 Antwort auf die Frage

1
Kamil Maciorowski

$steht weder in der Variable noch im Literal \r. Sie sind mit dem Ausgang hinzugefügt, weil Sie gesagt, auf printfdiese Weise zu formatieren: %q. Das eigentliche zusätzliche Zeichen ist "Wagenrücklauf", Code 0x0D, welche Escape-Sequenz ist \r.

Die Wurzel Ihres Problems ist, dass Ihre .xmlDateien anscheinend CR + LF-Zeilenenden aus der DOS / Windows-Welt verwenden. Siehe diesen Vergleich bei Wikipedia.

Das Dokument Extensible Markup Language (XML) 1.0 (Fünfte Ausgabe) sagt:

Um die Aufgaben von Anwendungen zu vereinfachen, muss sich der XML-Prozessor so verhalten, als ob er alle Zeilenumbrüche in externen geparsten Entitäten (einschließlich der Dokumententität) bei der Eingabe normalisiert hat, bevor er analysiert wird, indem er sowohl die aus zwei Zeichen bestehende Sequenz #xD #xAals auch jede andere, die #xDnicht folgt, übersetzt #xAzu einem einzelnen #xAZeichen.

Hier #xDbezeichnet CR, #xALF.

In Ihrem Fall die ganze find … | xargsAussage ist der XML - Prozessor (wir Probleme wie stellen diese beiseite). Wenn Sie die Spezifikation vollständig einhalten möchten, müssen Sie jede .xmlDatei dos2unixan erster Stelle durchgeben .

Da das eigentliche Problem jedoch mit dem Inhalt der Variablen zusammenhängt, kann dies in Ihrem Fall ausreichend sein:

var=`find … | dos2unix | xargs` 

Wenn Sie nicht haben dos2unix, tr -d '\r'würde in diesem Zusammenhang als Ersatz arbeiten (danke @GordonDavisson für diesen Hinweis).

Wenn Sie nicht über "dos2unix" verfügen, würde "tr -d" \ r "" in diesem Zusammenhang als Ersatz dienen. Gordon Davisson vor 6 Jahren 1
@ GordonDavisson Danke, das ist nützlich. Kamil Maciorowski vor 6 Jahren 0