Angenommen, ich habe zwei Variablen in bash:
MULTILINE="I have
more than one line"
SINGLE_LINE="I only have one line
"
Ich möchte erkennen, wann eine Variable tatsächlich mehr als eine Textzeile enthält, ohne zusätzliche nachgestellte Zeilenumbrüche.
Also das:
if [ some test on "$MULTILINE" ]; then echo 'yes'; else echo 'no'; fi
würde drucken yes
, und dies:
if [ some test on "$SINGLE_LINE" ]; then echo 'yes'; else echo 'no'; fi
würde drucken no
.
Für meinen speziellen Fall glaube ich nicht, dass ich mir Gedanken über das Führen von Leerzeilen machen muss, aber es würde nicht schaden, zu wissen, wie das geht.
Wie kann ich das machen?
Antworten:
Die einfachste Lösung, die ich kenne, ist:
z.B:
==>
Das Obige ignoriert alle Leerzeilen: führend, nachlaufend und innen. Beachten Sie jedoch, dass es nicht möglich ist, eine innere Leerzeile zu haben, wenn nicht mindestens zwei nicht leere Zeilen vorhanden sind. Daher kann ihre Existenz die Frage nicht ändern, ob nach dem Trimmen der führenden und nachfolgenden Leerzeilen mehr als eine Zeile vorhanden ist.
quelle
Weitere Informationen
zum Trimmen / Löschen von Leerzeichen und Leerzeilen mit sed finden Sie unter /programming/16414410/delete-empty-lines-using-sed .
Schreiben Sie nun Ihre
if expression ...
Verwendung$( ... )
in Anführungszeichen, um die Anzahl der Zeilen zu ermitteln, und testen Sie sie anhand der Anzahl:quelle
Eine geringfügige Änderung dieses Codes sollte dies tun. Sie können es in ein eigenes Skript einfügen, um es wie folgt wiederzuverwenden:
Dann können Sie es so verwenden (vorausgesetzt, Sie haben das vorherige Skript benannt
multiline-check.sh
):quelle
fi
. Leider stecke ich bei Bash 3.1 (msysgit-Version) fest. Ich sehe nichts, was für mich wie ein Syntaxfehler aussieht, aber offensichtlich fehlt mir etwas. Gedanken?Nachgestellte Leerzeilen ignorieren
Hier ist ein Ansatz mit
awk
:Wie es funktioniert:
Echo "$ TEST"
Dies nimmt jede Shell-Variable, an der wir interessiert sind, und sendet sie an Standard Out.
tac
Dies kehrt die Reihenfolge der Zeilen um, sodass die letzte Zeile zuerst zurückgegeben wird. Nach der Ausführung
tac
werden die nachfolgenden Zeilen zu den führenden Zeilen.(Der Name
tac
ist die Umkehrung voncat
aus dem Grund, dertac
tut, wascat
tut, aber umgekehrt.)awk 'f==0 && /./ {f=NR} END{if(f==NR){exit 0}; exit 1 }'
Dies speichert die Zeilennummer der ersten nicht leeren Zeile in der Variablen
f
. Nach dem Einlesen aller Zeilen wirdf
die Gesamtzahl der Zeilen verglichenNR
. Wennf
gleich ist,NR
hatten wir nur eine einzige Zeile (wobei die anfänglichen Leerzeichen ignoriert wurden) und beenden mit Code 0. Wenn nach der ersten leeren Zeile eine oder mehrere Zeilen stehen, wird sie mit Code `beendet.&& echo "Found A Single Line"
Wenn
awk
mit Code 0 beendet, wird dieecho
Anweisung ausgeführt.Ignorieren sowohl führender als auch nachfolgender Leerzeilen
Durch Erstellen einer zusätzlichen
awk
Variablen können wir den Test erweitern, um sowohl führende als auch nachfolgende Leerzeilen zu ignorieren:Da diese Version des
awk
Codes sowohl führende als auch nachfolgende Leerzeichen verarbeitet,tac
wird sie nicht mehr benötigt.Nehmen Sie den
awk
Code Stück für Stück:first==0 && /./ {first=NR}
Wenn die Variable
first
Null ist (oder noch nicht festgelegt wurde) und die Zeile ein Zeichen oder ein beliebiges Zeichen enthält, wirdfirst
die Zeilennummer festgelegt. Wennawk
das Lesen der Zeilen abgeschlossen ist,first
wird die Zeilennummer der ersten nicht leeren Zeile festgelegt././ {last=NR}
Wenn die Zeile ein Zeichen enthält, setzen Sie die Variable
last
auf die aktuelle Zeilennummer. Wennawk
alle Zeilen gelesen sind, hat diese Variable die Zeilennummer der letzten nicht leeren Zeile.END{if(first==last){exit 0}; exit 1 }
Dies wird ausgeführt, nachdem alle Zeilen gelesen wurden. Wenn
first
gleich istlast
, haben wir null oder nicht leere Zeilen gesehen und werdenawk
mit Code beendet0
. Andernfalls wird es mit Code beendet1
. Das Shell-Skript kann den Exit-Code wie gewohnt mitif
Anweisungen oder&&
oder testen||
.quelle