Der Befehl tr hat keine Wirkung, wenn er in $() verwendet und in einer Variablen gespeichert wird.

Der Befehl tr hat keine Wirkung, wenn er in $() verwendet und in einer Variablen gespeichert wird.

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, echoes 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 trignoriert 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 longeine Fehlermeldung. Irgendwelche Vorschläge?

Antwort1

Laut der bashManpage 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 trist also nicht das Problem, sondern es bashwerden 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 somefileIhre 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.

verwandte Informationen