web-dev-qa-db-fra.com

Dans bash, comment compter le nombre de lignes dans une variable?

j'ai un fichier var qui contient une chaîne et je dois vérifier s'il contient des lignes:

var=`ls "$sdir" | grep "$input"`

pseudocode:

while [ ! $var's number of lines -eq 1 ]
  do something

c’est mon idée sur la façon de vérifier, echo $var | wc -l ne fonctionne pas, il dit toujours 1 même s’il en a 3

echo -e ne fonctionne pas

49
krack krackerz

Les citations comptent.

echo "$var" | wc -l
79

La réponse acceptée et les autres réponses publiées ici ne fonctionnent pas dans le cas d'une variable vide (chaîne non définie ou vide).

Cela marche:

echo -n "$VARIABLE" | grep -c '^'

Par exemple:

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
44
Julian

Une autre façon d'utiliser here strings dans bash:

wc -l <<< "$var"

Comme mentionné dans ce commentaire , un $var vide donnera 1 ligne au lieu de 0 parce que here chaines ajoute un caractère de nouvelle ligne dans ce cas ( explication ).

19
speakr

Vous pouvez remplacer "wc -l" par "wc -w" pour compter plutôt le nombre de mots que de lignes. Cela ne comptera aucune nouvelle ligne et pourra être utilisé pour tester si vos résultats d'origine sont vides avant de continuer.

8

Les réponses les plus votées échouent si aucun résultat n'a été renvoyé par un grep.

Homer Simpson
Marge Simpson
Bart Simpson
Lisa Simpson
Ned Flanders
Rod Flanders
Todd Flanders
Moe Szyslak

C'est le mauvais moyen de le faire :

wiggums=$(grep -iF "Wiggum" characters.txt);
num_wiggums=$(echo "$wiggums" | wc -l);
echo "There are ${num_wiggums} here!";

Il nous dira qu'il y a 1Wiggum _ dans la liste, même s'il n'y en a pas.

Au lieu de cela, vous devez effectuer une vérification supplémentaire pour voir si la variable est vide (-z, comme dans "est zéro"). Si grep n'a rien renvoyé, la variable sera vide.

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";
3
Jonathan Matthews

Personne n’a mentionné l’expansion des paramètres. Il existe donc deux façons d’utiliser pur bash.

Méthode 1

Supprimez les caractères qui ne sont pas des sauts de ligne, puis récupérez la longueur de chaîne + 1. Les guillemets sont importants.

 var="${var//[!$'\n']/}"
 echo $((${#var} + 1))

Méthode 2

Convertir en tableau, puis obtenir la longueur du tableau. Pour que cela fonctionne, n'utilisez pas de guillemets.

 var=(${var})
 echo ${#var[@]}
1
haqk

Une version plus simple de la réponse de @ Julian, qui fonctionne pour toutes les chaînes de caractères, avec ou sans fin (\ n) (elle ne compte qu'un fichier contenant seulement un seul\n fin):

printf "%s" "$a" | grep -c "^"

  • Renvoie zéro: variable non définie, chaîne vide, chaîne contenant une nouvelle ligne nue
  • Retourne 1: toute ligne non vide, avec ou sans nouvelle ligne.
  • etc

Sortie:

# 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
0
Stilez