Hier ist das Problem ist, dass Sie die Variable mit doppelten Anführungszeichen umgeben ( „“). Entfernen Sie es und die Dinge werden gut funktionieren.
VAR="This displays with \
extra spaces."
echo ${VAR}
Ausgabe
This displays with extra spaces.
Hier ist das Problem, dass eine doppelte eine Variable unter Angabe erhält alle Leerzeichen. Dies kann verwendet werden, wenn Sie es ausdrücklich benötigen.
Zum Beispiel,
$ echo "Hello World ........ ... ...."
wird gedruckt
Hello World ........ ... ....
Und beim Entfernen von Anführungszeichen ist es anders
$ echo Hello World ........ ... ....
Hello World ........ ... ....
Hier entfernt der Bash zusätzliche Leerzeichen im Text, da im ersten Fall der gesamte Text als "einzelnes" Argument interpretiert wird und somit zusätzliche Leerzeichen erhalten bleiben. Im zweiten Fall echo
erhält der Befehl den Text als 5 Argumente.
Zitiert eine Variable wird auch hilfreich, während Argumente auf Befehle übergeben.
Im folgenden Befehl wird echo
nur ein einziges Argument als abgerufen"Hello World"
$ variable="Hello World"
$ echo "$variable"
Aber im Fall des folgenden Szenarios echo
erhält man zwei Argumente als Hello
undWorld
$ variable="Hello World"
$ echo $variable
$IFS
sind ein leistungsfähiges und universelles Werkzeug - aber so geschriebener Code kann niemals zuverlässige Ergebnisse jeglicher Art liefern.*
?
[]
).Die Lösungen von esuoxu und Mickaël Bucas sind die gebräuchlichsten und portableren Methoden, um dies zu erreichen.
Hier sind einige
bash
Lösungen (von denen einige auch in anderen Shells funktionieren sollten, wie zzsh
. B. ). Erstens mit dem+=
Append-Operator (der für eine Ganzzahlvariable, eine reguläre Variable und ein Array jeweils auf etwas andere Weise funktioniert).Wenn Sie Zeilenumbrüche (oder andere Leerzeichen / Escapezeichen) im Text verwenden möchten, verwenden Sie
$''
stattdessen Anführungszeichen :Als Nächstes
printf -v
weisen Sie einer Variablen mit einen formatierten Wert zuDer Trick dabei ist, dass es mehr Argumente als Formatbezeichner gibt. Im Gegensatz zu den meisten
printf
Funktionen verwendet die Bash die Formatzeichenfolge so lange, bis sie leer ist. Sie können eine\n
Zeichenfolge in das Format einfügen oder $ '' (oder beide) verwenden, um mit Leerzeichen umzugehen.Als nächstes verwenden Sie ein Array:
Sie können
+=
den Text auch zeilenweise aufbauen (beachten Sie das()
):Hier müssen Sie jedoch daran denken, das Array zu "verflachen", wenn Sie den gesamten Textinhalt auf einmal benötigen
(Ganzzahlige indizierte Arrays werden im Gegensatz zu assoziativen Arrays implizit sortiert.) Dies gibt Ihnen etwas mehr Flexibilität, da Sie Linien manipulieren und bei Bedarf sogar schneiden und würfeln können.
Zum Schluss mit
read
oderreadarray
und einem "hier-Dokument":Die Form "Hier-Dokument"
<<-
bedeutet, dass alle führenden harten Tabulatoren aus der Eingabe entfernt werden. Daher müssen Sie Tabulatoren verwenden, um Ihren Text einzurücken. Anführungszeichen"EOT"
verhindern Shell-Erweiterungsfunktionen, sodass die Eingabe wörtlich verwendet wird. Dabeiread
wird eine durch NUL-Bytes begrenzte Eingabe verwendet, sodass der durch Zeilenumbrüche begrenzte Text auf einmal gelesen wird. Mitreadarray
(akamapfile
, verfügbar seit Bash-4.0) liest es in ein Array und entfernt-t
Zeilenumbrüche in jeder Zeile.quelle
read
Option mithere document
ist sehr schön! Nützlich, um Python-Skripte einzubetten und mit auszuführenpython -c
. Früher habe ich das gemachtscript=$(cat <here document>)
, aber esread -r -d '' script <here document>
ist viel besser.Es gibt eine spezielle Heredoc-Syntax, mit der Tabulatoren am Anfang aller Zeilen entfernt werden: "<< -" (beachten Sie den hinzugefügten Bindestrich)
http://tldp.org/LDP/abs/html/here-docs.html
Beispiel 19-4. Mehrzeilige Nachricht mit unterdrückten Tabulatoren
Du kannst es so benutzen:
Ergebnis:
Es funktioniert nur mit Tabulatoren, nicht mit Leerzeichen.
quelle
\t
Funktioniert jedoch hervorragend, wenn Sie Registerkarten benötigen. Verwenden Sie einfach,echo -e "$v"
anstattecho "$v"
Backslash-Zeichen zu aktivierenLassen Sie die Shell die unerwünschten Zeilenvorschübe und die folgenden Leerzeichen essen:
Es ist also möglich ... aber sicher ist es Geschmackssache, diese Lösung zu mögen oder nicht zu mögen ...
quelle
Vielleicht kannst du es versuchen.
quelle
So schlage ich vor, Sie sollten es tun, und ich werde erklären, warum, aber zuerst möchte ich über etwas anderes sprechen ...
Viele der anderen hier angebotenen Lösungen scheinen darauf hinzudeuten, dass Sie den Inhalt einer Shell-Variablen irgendwie beeinflussen können, indem Sie ihre Erweiterungsmethoden ändern. Ich kann Ihnen versichern, dass dies nicht der Fall ist.
AUSGABE
Was Sie oben sehen, ist zuerst eine feldgeteilte Erweiterung, dann ein Bericht über die Byteanzahl für die Quellvariable der Erweiterung, dann eine durch Anführungszeichen getrennte Erweiterung und dieselbe Byteanzahl. Während die Ausgabe unterschiedlich sein kann,
$string
ändert sich der Inhalt der Shell-Variablen nur bei Zuweisung.Was mehr ist, wenn Sie nicht verstehen, warum dies so ist, werden Sie früher als später auf einige sehr böse Überraschungen stoßen. Versuchen wir es noch einmal, aber unter etwas anderen Bedingungen.
Gleich
$string
- andere Umgebung.AUSGABE
Die Feldaufteilung erfolgt anhand der in definierten Feldbegrenzer
$IFS
. Es gibt zwei Arten von Begrenzern -$IFS
Leerzeichen und$IFS
alles andere. Standardmäßig$IFS
wird der Wertebereichsregisterkarte Zeilenumbruch zugewiesen - dies sind die drei möglichen$IFS
Leerzeichenwerte. Sie lässt sich jedoch leicht ändern, wie Sie oben sehen, und kann drastische Auswirkungen auf die Field-Split-Erweiterungen haben.$IFS
Whitespace wird durch Sequenzierung in ein einzelnes Feld zerlegt - und aus diesem Grund wirdecho
eine Erweiterung, die eine beliebige Folge von Leerzeichen$IFS
enthält, wenn sie ein Leerzeichen enthält, nur zu einem einzelnen Leerzeichen ausgewertet, daecho
die Argumente für Leerzeichen verkettet werden. Nicht-Whitespace-Werte werden jedoch nicht auf die gleiche Weise entfernt, und jeder vorkommende Begrenzer erhält immer ein Feld für sich - wie aus der obigen Stuff- Erweiterung hervorgeht.Das ist nicht das Schlimmste. Betrachten Sie diesen anderen
$string
.AUSGABE
Sieht ok aus, oder? Nun, lassen Sie uns die Umgebung noch einmal ändern.
AUSGABE
Woah.
Standardmäßig erweitert die Shell Dateinamen-Globs, wenn sie mit ihnen übereinstimmen können. Dies geschieht nach der Parametererweiterung und der Aufteilung der Felder in der angegebenen Reihenfolge. Daher ist jede nicht in Anführungszeichen gesetzte Zeichenfolge auf diese Weise anfällig. Sie können dieses Verhalten mit
set -f
deaktivieren, wenn Sie möchten, aber jede POSIX-kompatible Shell wird standardmäßig immer glob sein.Dies ist die Art von Dingen, mit denen Sie konfrontiert sind, wenn Sie Erweiterungen in Anführungszeichen setzen, um sie Ihren Einzugspräferenzen anzupassen. Und
$string
trotzdem ist der tatsächliche Wert für unabhängig von seinem Expansionsverhalten immer noch der Wert, den Sie zuletzt zugewiesen haben. Kommen wir also zum ersten Punkt zurück.AUSGABE
Ich glaube, dies ist eine weitaus vernünftigere Möglichkeit, die Shell-Syntax an Ihre Einzugspräferenzen anzupassen. Was ich oben mache, ist die Zuweisung jeder einzelnen Zeichenfolge zu einem Positionsparameter - auf den jeweils durch eine Zahl wie
$1
oder verwiesen werden kann${33}
- und anschließend die Zuweisung ihrer verketteten Werte zur$var
Verwendung des speziellen Shell-Parameters$*
.Dieser Ansatz ist jedoch nicht immun gegen
$IFS
. Dennoch halte ich seine Beziehung$IFS
in dieser Hinsicht für einen zusätzlichen Nutzen. Erwägen:AUSGABE
Wie Sie sehen können, wird
$*
jedes Argument im"$@"
ersten Byte im verkettet$IFS
. Wenn Sie also den Wert speichern, während er$IFS
unterschiedlich zugewiesen ist, erhalten Sie für jeden gespeicherten Wert unterschiedliche Feldbegrenzer. Was Sie oben sehen, ist übrigens der Literalwert für jede Variable. Wenn Sie überhaupt kein Trennzeichen möchten, würden Sie Folgendes tun:AUSGABE
quelle
Vielleicht möchten Sie versuchen:
oder
und Sie können dies auch überprüfen .
quelle
Verwenden Sie eine Bash-Substitution-Erweiterung
Wenn Sie Bash verwenden, können Sie eine Substitutionserweiterung verwenden . Zum Beispiel:
quelle
Dies ist eine Variante zum Setzen von pfadähnlichen Variablen:
Verwenden von
set
Überschreibungen$@
, die wie folgt gespeichert und später verwendet werden können:Die
LD_LIBRARY_PATH=$(sed 's/ :/:/g' <<< $LD_LIBRARY_PATH)
Zeile entfernt Leerzeichen vor Doppelpunkten sowie eventuell nachfolgende Leerzeichen. Verwenden SieLD_LIBRARY_PATH=${LD_LIBRARY_PATH%% }
stattdessen, wenn Sie nur nachfolgende Leerzeichen entfernen.Dieser gesamte Ansatz ist eine Variante der hervorragenden Antwort von mikeserv.
quelle
Hab keine Angst vor Leerzeichen. Entfernen Sie sie einfach, bevor Sie Ihren mehrzeiligen Text drucken.
Ausgabe:
Sie müssen keinen
<<-
Heredoc verwenden und Ihre Einrückung mit vier Leerzeichen nicht durch Tabulatorzeichen trennen.quelle