%20verwendet%20und%20in%20einer%20Variablen%20gespeichert%20wird..png)
Wenn ich in der CLI ausführe:
curl time.com | sed -n 's/.*href="\([^"]*\).*/\1/p' | tr " " "\n"
dann erhalte ich wie erwartet eine Liste bereinigter Links von der Seite zu STDOUT
, jeweils in einer neuen Zeile.
Wenn ich das jedoch in einer Variablen speichere und versuche, echo
es von einem script.sh
:
PAGE_LINKS=$(curl time.com | sed -n 's/.*href="\([^"]*\).*/\1/p' | tr " " "\n")
echo $PAGE_LINKS
Ich bekomme alle Links in einer Zeile, durch Leerzeichen getrennt. Als ob das tr
ignoriert worden wäre.
Ich habe mehrere Dinge ausprobiert, darunter so etwas wie
HREFS=$(tr " " "\n" < "{PAGE_LINKS}")
echo $HREFS
Aber dann bekomme ich file too long
eine Fehlermeldung. Irgendwelche Vorschläge?
Antwort1
Laut der bash
Manpage für die $(command)
Konstruktion:
Bash führt die Erweiterung durch, indem es den Befehl ausführt und die Befehlssubstitution durch die Standardausgabe des Befehls ersetzt, wobei alle nachfolgenden Zeilenumbrüche gelöscht werden. Eingebettete Zeilenumbrüche werden nicht gelöscht, können aber während der Worttrennung entfernt werden.
Das tr
ist also nicht das Problem, sondern es bash
werden entweder die Zeilenumbrüche gelöscht, wenn sie am Ende stehen, oder alle anderen Zeilenumbrüche während der Worttrennung entfernt. Dies ist das dokumentierte Verhalten.
Ich glaube, dieses Verhalten ist an den meisten Stellen erwünscht. Wenn Sie eine Datei mit einer Liste von Dateinamen haben, dann:
for FILENAME in $(cat somefile)
do
...
done
Iteriert über die Liste der Dateinamen. Sie möchten nicht, dass die Zeilenumbrüche somefile
Ihre Liste der als Dateinamen zu verwendenden Wörter durcheinanderbringen und möglicherweise sogar Ihre For-Do-Done-Schleife durcheinanderbringen.
Antwort2
Das Problem liegt nicht darin tr
, sondern darin, wie Sie die Variablenerweiterung ausgeben:
echo $PAGE_LINKS
Zitieren Sie die Variablenerweiterung:
echo "$PAGE_LINKS"
Andernfalls erfolgt die Erweiterung durch Worttrennung entsprechend dem Wert von IFS
(standardmäßig Leerzeichen, Tabulator, Zeilenumbruch) und Pfadnamenerweiterung ( *
, ?
, []
).
In Ihrem Fall findet die Worttrennung statt, und jedes durch Zeilenumbrüche getrennte Element wird einzeln genommen und schließlich als durch Leerzeichen getrennte Einheiten angezeigt. Die Verwendung von Anführungszeichen verhindert die Worttrennung (und die Pfadnamenerweiterung), sodass die gesamte Erweiterung als einzelne Einheit genommen wird.