Ich habe eine Variable, in der eine Zeichenfolge gespeichert ist, und muss überprüfen, ob sie Zeilen enthält:
var=`ls "$sdir" | grep "$input"`
Pseudocode:
while [ ! $var's number of lines -eq 1 ]
do something
Das ist meine Idee, wie ich es überprüfen soll. echo $var | wc -l
funktioniert nicht - es heißt immer 1
, obwohl es hat 3
.
echo -e
funktioniert nicht so gut.
if [ -z "$var" ]; then printf '%s\n' '0'; else printf '%s\n' "${var%$'\n'}" | wc -l; fi
. Versuchen Sie es mitvar=
(keine Zeilen)var='foo'
undvar=$'foo\n'
(beide eine Zeile im Sinne von * nix).LINE_COUNT=$(wc -l <<< "${var}")
echo -n
verringert einfach die Anzahl um eins. @ Lucifuriousecho $(wc -l <<< "${NONEXISTENTVAR}")
gibt immer noch 1, nicht 0Die akzeptierte Antwort und andere hier veröffentlichte Antworten funktionieren bei einer leeren Variablen (undefinierte oder leere Zeichenfolge) nicht.
Das funktioniert:
echo -n "$VARIABLE" | grep -c '^'
Zum Beispiel:
ZERO= ONE="just one line" TWO="first > second" echo -n "$ZERO" | grep -c '^' 0 echo -n "$ONE" | grep -c '^' 1 echo -n "$TWO" | grep -c '^' 2
quelle
WHITESPACE_ONE=' '
in meiner Shell (Bash) funktioniert es immer noch, eine Zeile korrekt zu melden.printf
eher mit als vereinfacht werdenecho -n
. Ich habe dies als alternative Antwort hinzugefügt, um Testergebnisse aufzunehmen. Siehe unten.Eine andere Möglichkeit, hier Zeichenfolgen in Bash zu verwenden:
wc -l <<< "$var"
Wie in diesem Kommentar erwähnt , führt ein Leerzeichen zu
$var
1 Zeile anstelle von 0 Zeilen, da hier Zeichenfolgen in diesem Fall ein Zeilenumbruchzeichen hinzufügen ( Erläuterung ).quelle
wc -l <<<"$(echo "$var")"
(Ja, jedes einzelne Symbol war notwendig)$var
?var
enthält : Du hast das mit nichts interpretiert . Fügen Sie mehrere Zeilen in Ihre ein und es wird funktionieren, z . B. mit .\n
var
var="foo<ENTER>bar<ENTER>baz"<ENTER>
xxd <<< ''
Erstelle diesen Hexdump00000000: 0a
.<<<
Fügen Sie daher (Here Strings) jedem Inhalt ein Zeilenumbruchzeichen hinzu.Sie können "wc -l" durch "wc -w" ersetzen, um die Anzahl der Wörter anstelle von Zeilen zu zählen. Dies zählt keine neuen Zeilen und kann verwendet werden, um zu testen, ob Ihre ursprünglichen Ergebnisse leer sind, bevor Sie fortfahren.
quelle
wc -l
Lösungen gibt 1 aus, auch wenn die Eingabevariable leer ist. Daher istwc -w
es besser, sie zu verwenden.Niemand hat die Parametererweiterung erwähnt, daher gibt es hier einige Möglichkeiten, Pure Bash zu verwenden.
Methode 1
Entfernen Sie nicht neue Zeilen und erhalten Sie dann die Zeichenfolgenlänge + 1. Anführungszeichen sind wichtig .
var="${var//[!$'\n']/}" echo $((${#var} + 1))
Methode 2
In Array konvertieren, dann Array-Länge abrufen. Verwenden Sie keine Anführungszeichen, damit dies funktioniert .
set -f # disable glob (wildcard) expansion IFS=$'\n' # let's make sure we split on newline chars var=(${var}) echo ${#var[@]}
quelle
IFS
. So setzt ,IFS=$'\n'
um sicherzustellen , dass der Variable auf neue Zeilen aufgeteilt wird , wenn es in ein Array erweitert:IFS=$'\n'; var=(${var})
set -f
wird benötigt, um unerwünschte Glob-Expansion zu vermeiden. Versuchen Sie, Methode 2 anzuwendenvar=$'*\n.*'
.Eine einfachere Version von @ Julians Antwort, die für alle Zeichenfolgen mit oder ohne Trailing funktioniert \ n (eine Datei mit nur einem Trailing \ n wird als leer gezählt):
printf "%s" "$a" | grep -c "^"
Ausgabe:
# a= # printf "%s" "$a" | grep -c "^" 0 # a="" # printf "%s" "$a" | grep -c "^" 0 # a="$(printf "")" # printf "%s" "$a" | grep -c "^" 0 # a="$(printf "\n")" # printf "%s" "$a" | grep -c "^" 0 # a="$(printf " \n")" # printf "%s" "$a" | grep -c "^" 1 # a="$(printf " ")" # printf "%s" "$a" | grep -c "^" 1 # a="aaa" # printf "%s" "$a" | grep -c "^" 1 # a="$(printf "%s" "aaa")" # printf "%s" "$a" | grep -c "^" 1 # a="$(printf "%s\n" "aaa")" # printf "%s" "$a" | grep -c "^" 1 # a="$(printf "%s\n%s" "aaa" "bbb")" # printf "%s" "$a" | grep -c "^" 2 # a="$(printf "%s\n%s\n" "aaa" "bbb")" # printf "%s" "$a" | grep -c "^" 2
quelle
echo
(z. B.echo -n
) ist kein Standard und kann bei verschiedenen Implementierungen zu unterschiedlichen Ergebnissen führen. Währendprintf
macht, was wir standardmäßig wollen. Als Bonusprintf
erspart Ihnen die Verwendung einen Prozess, da es sich um eine integrierte Shell handelt. (Vorschlag:printf "$a" | wc -l
ist prägnanter und vermeidet unnötige Verwendung vongrep
)printf .... | wc -l
wird nur eine zusätzliche Zeile (die neue Zeile) entfernt, so dass im Falle einer leeren Zeile das Ergebnis 0 ist . Richtig. Aber wenn wir zwei Linien passieren, wird das Ergebnis 1, wo die gleiche Variable auf den übergebenenprintf ... | grep "^"
korrekt zurück 2. Außerdem direkt mitprintf "$a"
ist sehr gefährlich, weil es zu stillen Fehlern führen kann , wenn die Zeichenfolge versehentlich Zeichen enthält wie%s
,%d
und so on ... Gleich, wenn die Zeichenfolge mit einem Bindestrich beginnt. Stattdessen wird der 2-Parameter inprintf
automatischDie am besten bewerteten Antworten schlagen fehl, wenn keine Ergebnisse von einem Grep zurückgegeben wurden.
Dies ist der falsche Weg :
wiggums=$(grep -iF "Wiggum" characters.txt); num_wiggums=$(echo "$wiggums" | wc -l); echo "There are ${num_wiggums} here!";
Es wird uns sagen, dass
1
Wiggum in der Liste ist, auch wenn es keine gibt.Stattdessen müssen Sie eine zusätzliche Überprüfung durchführen, um festzustellen, ob die Variable leer ist (
-z
wie in "ist Null"). Wenn grep nichts zurückgegeben hat, ist die Variable leer.matches=$(grep -iF "VanHouten" characters.txt); if [ -z "$matches" ]; then num_matches=0; else num_matches=$(echo "$matches" | wc -l); fi echo "There are ${num_matches} VanHoutens on the list";
quelle
Eine andere Methode, um die Anzahl der Zeilen in einer Variablen zu zählen - vorausgesetzt, Sie haben überprüft, ob sie erfolgreich gefüllt wurde oder nicht leer ist. Überprüfen Sie dazu einfach $? nach var Subshell Ergebnisbeeinflussung -:
readarray -t tab <<<"${var}" echo ${#tab[@]}
readarray | mapfile ist ein interner Bash-Befehl, der die Eingabedatei oder in diesem Fall die Zeichenfolge in ein Array konvertiert, das auf Zeilenumbrüchen basiert.
Das Flag -t verhindert das Speichern von Zeilenumbrüchen am Ende der Zellen des Arrays, was für die spätere Verwendung gespeicherter Werte nützlich ist
Vorteile dieser Methode sind:
quelle
So vermeiden Sie Dateinamen im Befehl "wc -l":
lines=$(< "$filename" wc -l) echo "$lines"
quelle