Interprétez PATTERN comme une liste de chaînes fixes, séparées par des sauts de ligne, dont chacune doit être mise en correspondance.
-x, --line-regexp
Sélectionnez uniquement les correspondances qui correspondent exactement à toute la ligne.
-q, --quiet,--silent
Silencieux; n'écrivez rien sur la sortie standard. Quittez immédiatement avec l'état zéro si une correspondance est trouvée, même si une erreur a été détectée. Voir également l' option -sou --no-messages.
La gestion des erreurs
Comme indiqué à juste titre dans les commentaires, l'approche ci-dessus traite silencieusement les cas d'erreur comme si la chaîne avait été trouvée. Si vous souhaitez gérer les erreurs d'une manière différente, vous devrez omettre l' -qoption et détecter les erreurs en fonction de l'état de sortie:
Normalement, l'état de sortie est 0 si des lignes sélectionnées sont trouvées et 1 sinon. Mais l'état de sortie est 2 si une erreur s'est produite, sauf si l' option -qou --quietou --silentest utilisée et qu'une ligne sélectionnée est trouvée. Notez toutefois que seuls les mandats, POSIX pour des programmes tels que grep, cmpet diffque l'état de sortie en cas d'erreur soit supérieur à 1; il est donc conseillé, pour des raisons de portabilité, d'utiliser une logique qui teste cette condition générale au lieu d'une stricte égalité avec 2.
Pour supprimer la sortie normale de grep, vous pouvez la rediriger vers /dev/null. Notez que l'erreur standard reste non dirigée, donc tous les messages d'erreur qui greppourraient s'imprimer se retrouveront sur la console comme vous le voudriez probablement.
Pour gérer les trois cas, nous pouvons utiliser une caseinstruction:
case`grep -Fx "$FILENAME" "$LIST" >/dev/null; echo $?`in0)# code if found;;1)# code if not found;;*)# code if an error occurred;;esac
Si j'exécute cette commande à partir du script bash, comment attraper 0 ou 1 dans une variable?
Toren
6
@Toren Le statut de sortie le plus récent est accessible à l'aide de $?. vous pouvez également utiliser la commande grep à côté de l' ifinstruction (comme indiqué dans la réponse mise à jour).
Shawn Chin
5
Vous pouvez utiliser grep -Fqx "$FILENAME"et vous n'avez pas à vous soucier des caractères regex dans le contenu des variables et vous n'aurez pas à les utiliser dans la chaîne de recherche.
pause jusqu'à nouvel ordre.
4
Quelques notes pour les gens qui regardent cette réponse: 1) En bash, 0 est toujours vrai et tout le reste est toujours faux 2) N'utilisez l'indicateur -x que si vous voulez que la ligne entière corresponde exactement. Si vous voulez simplement savoir si votre chaîne existe dans le fichier, laissez-la désactivée. Si vous voulez trouver si votre chaîne existe exactement mais sans correspondre nécessairement à une ligne entière (c'est-à-dire comme un mot entier), utilisez -w.
Schmick
1
Je ne comprends pas le -q / --silentbesoin? Son dit faussement "tout va bien" à bash même si une erreur se produit. Si j'ai bien compris. Semble un concept défectueux pour ce cas.
redanimalwar
90
Concernant la solution suivante:
grep -Fxq"$FILENAME" my_list.txt
Au cas où vous vous demandez (comme je l'ai fait) ce que -Fxqsignifie en anglais simple:
F: Affecte la façon dont le motif est interprété (chaîne fixe au lieu d'une expression régulière)
x: Correspondre à toute la ligne
q: Shhhhh ... impression minimale
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.)
-F n'affecte pas le traitement des fichiers, il affecte la façon dont le MOTIF est interprété. En règle générale, PATTERN est interprété comme une expression régulière, mais avec -F, il sera interprété comme une chaîne fixe.
Adam S
41
Trois méthodes dans mon esprit:
1) Court test pour un nom dans un chemin (je ne suis pas sûr que ce soit votre cas)
ls -a "path"| grep "name"
2) Court test pour une chaîne dans un fichier
grep -R "string""filepath"
3) Script bash plus long utilisant l'expression régulière:
#!/bin/bash
declare file="content.txt"
declare regex="\s+string\s+"
declare file_content=$( cat "${file}")if[[" $file_content "=~ $regex ]]# please note the space before and after the file contentthen
echo "found"else
echo "not found"fi
exit
Cela devrait être plus rapide si vous devez tester plusieurs chaînes sur un contenu de fichier en utilisant une boucle, par exemple en changeant l'expression régulière à n'importe quel cicle.
Vous n'avez pas besoin de tester la sortie de grep, vous pouvez simplement utiliser grep -qet appeler grep directement ifcomme Thomas le fait dans sa réponse. De plus, la question ne comprenait pas de vérifier si le répertoire existe avant de l'ajouter à la liste (il pourrait s'agir d'une liste de répertoires supprimés, après tout).
sorpigal
J'ai supprimé l'exemple de script, cela n'ajoutait rien à la réponse donnée par Thomas.
lecodesportif
3
Si vous souhaitez simplement vérifier l'existence d'une ligne, vous n'avez pas besoin de créer de fichier. Par exemple,
if grep -xq "LINE_TO_BE_MATCHED" FILE_TO_LOOK_IN ;then# code for if it existselse# code for if it does not existfi
La solution de @ Thomas n'a pas fonctionné pour moi pour une raison quelconque, mais j'avais une chaîne plus longue avec des caractères spéciaux et des espaces, donc j'ai juste changé les paramètres comme ceci:
if grep -Fxq'string you want to find'"/path/to/file";then
echo "Found"else
echo "Not found"fi
Réponses:
Le statut de sortie est 0 (vrai) si le nom a été trouvé, 1 (faux) sinon, donc:
Explication
Voici les sections pertinentes de la page de manuel pour
grep
:La gestion des erreurs
Comme indiqué à juste titre dans les commentaires, l'approche ci-dessus traite silencieusement les cas d'erreur comme si la chaîne avait été trouvée. Si vous souhaitez gérer les erreurs d'une manière différente, vous devrez omettre l'
-q
option et détecter les erreurs en fonction de l'état de sortie:Pour supprimer la sortie normale de
grep
, vous pouvez la rediriger vers/dev/null
. Notez que l'erreur standard reste non dirigée, donc tous les messages d'erreur quigrep
pourraient s'imprimer se retrouveront sur la console comme vous le voudriez probablement.Pour gérer les trois cas, nous pouvons utiliser une
case
instruction:la source
$?
. vous pouvez également utiliser la commande grep à côté de l'if
instruction (comme indiqué dans la réponse mise à jour).grep -Fqx "$FILENAME"
et vous n'avez pas à vous soucier des caractères regex dans le contenu des variables et vous n'aurez pas à les utiliser dans la chaîne de recherche.-q / --silent
besoin? Son dit faussement "tout va bien" à bash même si une erreur se produit. Si j'ai bien compris. Semble un concept défectueux pour ce cas.Concernant la solution suivante:
Au cas où vous vous demandez (comme je l'ai fait) ce que
-Fxq
signifie en anglais simple:F
: Affecte la façon dont le motif est interprété (chaîne fixe au lieu d'une expression régulière)x
: Correspondre à toute la ligneq
: Shhhhh ... impression minimaleDepuis le fichier man:
la source
Trois méthodes dans mon esprit:
1) Court test pour un nom dans un chemin (je ne suis pas sûr que ce soit votre cas)
2) Court test pour une chaîne dans un fichier
3) Script bash plus long utilisant l'expression régulière:
Cela devrait être plus rapide si vous devez tester plusieurs chaînes sur un contenu de fichier en utilisant une boucle, par exemple en changeant l'expression régulière à n'importe quel cicle.
la source
Manière plus simple:
Astuce: envoyez à
/dev/null
si vous voulez l'état de sortie de la commande, mais pas les sorties.la source
-q
même chose que--quiet
:)-q
meilleure réponse également ici, et est la quatrième place. pas de justice dans ce monde.Le moyen le plus simple et le plus simple serait:
grep -c renverra le nombre de fois où la chaîne se produit dans le fichier.
la source
Si j'ai bien compris votre question, cela devrait faire ce dont vous avez besoin.
En une seule ligne :
check="/tmp/newdirectory"; [[ -n $(grep "^$check\$" my_list.txt) ]] && echo "dir already listed" || echo "$check" >> my_list.txt
la source
grep -q
et appeler grep directementif
comme Thomas le fait dans sa réponse. De plus, la question ne comprenait pas de vérifier si le répertoire existe avant de l'ajouter à la liste (il pourrait s'agir d'une liste de répertoires supprimés, après tout).Si vous souhaitez simplement vérifier l'existence d'une ligne, vous n'avez pas besoin de créer de fichier. Par exemple,
la source
Ma version utilisant fgrep
la source
-c
option dansfgrep --help
L'option -E oblige grep à utiliser des expressions régulières
la source
La solution de @ Thomas n'a pas fonctionné pour moi pour une raison quelconque, mais j'avais une chaîne plus longue avec des caractères spéciaux et des espaces, donc j'ai juste changé les paramètres comme ceci:
J'espère que cela aide quelqu'un
la source
Une solution sans grep, fonctionne pour moi:
basé sur: https://stackoverflow.com/a/229606/3306354
la source
grep -q
décrit dans la réponse acceptée est l'approche la plus efficace.la source
la source