Comment vérifier si un fichier contient une chaîne spécifique à l'aide de Bash

Réponses:

466
if grep -q SomeString "$File"; then
  Some Actions # SomeString was found
fi

Vous n'avez pas besoin [[ ]]ici. Exécutez simplement la commande directement. Ajoutez une -qoption lorsque vous n'avez pas besoin de la chaîne affichée lorsqu'elle a été trouvée.

La grepcommande renvoie 0 ou 1 dans le code de sortie en fonction du résultat de la recherche. 0 si quelque chose a été trouvé; 1 sinon.

$ echo hello | grep hi ; echo $?
1
$ echo hello | grep he ; echo $?
hello
0
$ echo hello | grep -q he ; echo $?
0

Vous pouvez spécifier des commandes comme condition de if. Si la commande renvoie 0 dans son code de sortie, cela signifie que la condition est vraie; sinon faux.

$ if /bin/true; then echo that is true; fi
that is true
$ if /bin/false; then echo that is true; fi
$

Comme vous pouvez le voir, vous exécutez ici les programmes directement. Pas supplémentaire []ou [[]].

Igor Chubin
la source
Plus d'informations grepet les options disponibles dans asnwer stackoverflow.com/a/4749368/1702557
Pawel
2
pourrait vouloir considérer les -Fxqparamètres comme dans stackoverflow.com/a/4749368/544721
Grzegorz Wierzowiecki
3
envisager d'utiliser -m 1afin d'améliorer les performances de numérisation. Retourne sur la première occurrence.
AlikElzin-kilaka
1
si SomeStringcontient des caractères spéciaux regex (comme .), vous pourriez obtenir des résultats inattendus. Il est plus sûr de toujours utiliser fgrep(ou grep -F) (sauf si vous avez vraiment besoin d'une expression régulière, auquel cas egrep(ou grep -E) est probablement le meilleur choix)
Walter Tross
L'exemple d' ifexemple est incorrect, car il vérifie uniquement si le code de sortie était différent de 0. Si une erreur se produit, comme le fichier ne peut pas être lu, le code de sortie est également différent de 0. Donc, vous devez faire quelque chose comme ça ec=$?, et vérifier si c'est 0(trouvé), puis si c'est 1(pas trouvé), puis si c'est autre chose (échouer).
ddekany
40

En plus d'autres réponses, qui vous ont dit comment faire ce que vous vouliez, j'essaie d'expliquer ce qui n'allait pas (c'est ce que vous vouliez.

Dans Bash, ifdoit être suivi d'une commande. Si le code de sortie de cette commande est égal à 0, alors la thenpartie est exécutée, sinon la elsepartie le cas échéant est exécutée.

Vous pouvez le faire avec n'importe quelle commande, comme expliqué dans d'autres réponses: if /bin/true; then ...; fi

[[est une commande bash interne dédiée à certains tests, comme l'existence de fichiers, les comparaisons de variables. De même [est une commande externe (elle se trouve généralement dans /usr/bin/[) qui effectue à peu près les mêmes tests mais a besoin ]comme argument final, c'est pourquoi ]doit être complétée avec un espace à gauche, ce qui n'est pas le cas ]].

Ici, vous n'avez pas besoin non [[plus [.

Une autre chose est la façon dont vous citez les choses. En bash, il n'y a qu'un seul cas où des paires de guillemets s'emboîtent, c'est le cas "$(command "argument")". Mais 'grep 'SomeString' $File'vous n'avez qu'un seul mot, car 'grep 'est une unité citée, qui est concaténée avec SomeStringpuis concaténée avec ' $File'. La variable $Filen'est même pas remplacée par sa valeur en raison de l'utilisation de guillemets simples. La bonne façon de le faire est grep 'SomeString' "$File".

Benoit
la source
15

Si vous souhaitez vérifier si le fichier ne contient pas de chaîne spécifique, vous pouvez le faire comme suit.

if ! grep -q SomeString "$File"; then
  Some Actions # SomeString was not found
fi
Lahiru Chandima
la source
10
##To check for a particular  string in a file

cd PATH_TO_YOUR_DIRECTORY #Changing directory to your working directory
File=YOUR_FILENAME  
if grep -q STRING_YOU_ARE_CHECKING_FOR "$File"; ##note the space after the string you are searching for
then
echo "Hooray!!It's available"
else
echo "Oops!!Not available"
fi
Nevin Raj Victor
la source
2
Changer de répertoire n'est généralement pas une bonne idée (et n'est absolument pas nécessaire ici, il suffit de qualifier le nom de fichier avec le répertoire cible). Et puis ce que vous avez est exactement la même chose que la réponse acceptée, mais avec moins de détails.
Mat
Merci pour les conseils Mat
Nevin Raj Victor
7

Version la plus courte (correcte):

grep -q "something" file; [ $? -eq 0 ] && echo "yes" || echo "no"

peut aussi s'écrire

grep -q "something" file; test $? -eq 0 && echo "yes" || echo "no"

mais vous n'avez pas besoin de le tester explicitement dans ce cas, donc la même chose avec:

grep -q "something" file && echo "yes" || echo "no"
lzap
la source
3
if grep -q something file; then echo yes; else echo no; fi. Aucune raison de jouer avec $?.
Charles Duffy
6

Dans le cas où vous voulez vérifier si la chaîne correspond à la ligne entière et s'il s'agit d'une chaîne fixe, vous pouvez le faire de cette façon

grep -Fxq [String] [filePath]

exemple

 searchString="Hello World"
 file="./test.log"
 if grep -Fxq "$searchString" $file
    then
            echo "String found in $file"
    else
            echo "String not found in $file"
 fi

Depuis le fichier man:

-F, --fixed-strings

          Interpret  PATTERN  as  a  list of fixed strings, separated by newlines, any of 

which is to be matched.
          (-F is specified by POSIX.)
-x, --line-regexp
          Select only those matches that exactly match the whole line.  (-x is specified by 

POSIX.)
-q, --quiet, --silent
          Quiet; do not write anything to standard output.  Exit immediately with zero 

status  if  any  match  is
          found,  even  if  an error was detected.  Also see the -s or --no-messages 

option.  (-q is specified by
          POSIX.)
Shubham Khatri
la source
6
grep -q [PATTERN] [FILE] && echo $?

Le statut de sortie est 0(vrai) si le modèle a été trouvé; sinon chaîne vide.

SupermanKelly
la source
4
if grep -q [string] [filename]
then
    [whatever action]
fi

Exemple

if grep -q 'my cat is in a tree' /tmp/cat.txt
then
    mkdir cat
fi
user5854766
la source
2

Essaye ça:

if [[ $(grep "SomeString" $File) ]] ; then
   echo "Found"
else
   echo "Not Found"
fi
vgokul129
la source
3
Je m'abstiens avec hésitation de voter contre cela, mais Stack Overflow ne devrait pas perpétuer ce type de logique de bretzel. greprenvoie un état de sortie pour une très bonne raison; capturer la sortie dans une chaîne va potentiellement stocker une grande quantité de texte dans un tampon juste pour que vous puissiez dire qu'il n'est pas vide.
tripleee
-1

Je l'ai fait, semble bien fonctionner

if grep $SearchTerm $FileToSearch; then
   echo "$SearchTerm found OK"
else
   echo "$SearchTerm not found"
fi
madarekrap
la source
La citation est rompue et vous voudrez probablement éviter de voir la sortie de grep.
tripleee du
-3
grep -q "something" file
[[ !? -eq 0 ]] && echo "yes" || echo "no"
chemila
la source
1
Vous avez une faute de frappe -!? est censé être $?
lzap
... non seulement il est prévu $?, mais il n'est pas nécessaire du tout - vous pouvez simplement le faireif grep -q ...
Charles Duffy
1
De plus, foo && truthy_action || falsey_actionn'est pas un véritable opérateur ternaire - en cas d' truthy_actionéchec, il falsey_actions'exécute en plus .
Charles Duffy
Plus généralement, le but de ifest d'exécuter une commande et de vérifier son code de sortie. Vous devriez très rarement avoir besoin d'examiner de manière $?explicite.
tripleee