Je cherche la chaîne ::=BEGIN
et je souhaite appliquer une condition pour vérifier si le mot a été trouvé.
Donc, ce que je veux dire est quelque chose dans ce sens:
if (sed command does find a match for "::=BEGIN")
then i=1
else i=0
De plus, je veux que le 1 (pour oui trouvé) et le 0 (non trouvé) soit mis dans la variable "i".
Sil te plait aide moi. Fournissez également une explication à la solution! Merci!
grep
fait ce travail assez bien.
$ echo "::=BEGIN" > testfile1.txt
$ grep "::=BEGIN" -q testfile1.txt && echo "FOUND"
FOUND
$ grep "::=BEGIN" -q testfile1.txt && echo "FOUND" || echo "NOTFOUND"
FOUND
$ grep "whever" -q testfile1.txt && echo "FOUND" || echo "NOTFOUND"
NOTFOUND
Le code ne fait que lancer une recherche silencieuse dans le sous-shell. &&
, ou l'opérande AND logique, vérifie si la première commande a abouti. Si c'est le cas, il exécute echo "FOUND"
. ||
vérifie si cet écho a été exécuté, c'est-à-dire si nous avons trouvé quelque chose. Le second écho ne s'exécute que si la première commande a échoué.
Voici une version awk
name__:
$ awk '{i="NOTFOUND";if($0~/::=BEGIN/) i="FOUNDIT";exit } END { print i}' testfile1.txt
FOUNDIT
$ awk '{i="NOTFOUND";if($0~/whatevs/) i="FOUNDIT";exit } END { print i}' testfile1.txt
NOTFOUND
L'idée de base est de définir i
sur NOTFOUND
et, si nous trouvons la chaîne, remplacez-la par FOUNDIT
name__. À la fin, une fois le premier fichier traité terminé, nous imprimerons i
et nous dirons si nous avons trouvé quelque chose ou non.
Edit: Dans le commentaire que vous avez indiqué, vous souhaitez placer le résultat dans une variable. Shell fournit déjà une variable qui indique le statut de sortie de la commande précédente, $0
. Le statut de sortie 0 signifie succès, tout le reste - échec. Par exemple,
$ grep "::=BEGIN" -q testfile1.txt
$ echo $?
0
Si vous souhaitez utiliser le statut de sortie dans une variable, vous pouvez le faire comme suit: MYVAR=$(echo $?)
. Rappelez-vous, $? signaler le statut de sortie de la commande précédente. Donc, vous devez utiliser ceci juste après la commande grep.
Si vous souhaitez continuer à utiliser mes précédentes lignes unies awk et grep, vous pouvez utiliser la même astuce MYVAR=$()
et placer la commande de votre choix entre les accolades. La sortie sera affectée à la variable MYVAR
name__.
Avec un GNU sed
--- (tel qu'il est installé par défaut sur tout système Ubuntu):
{ sed -n '/::=BEGIN/Q 1'; i=$?; } <infile
Quelques faits sur cette réponse:
sed
Q
uits dès que le toute première correspondance se trouve n'importe où dans le fichier - ce qui signifie qu'il ne perd plus de temps à lire l'info-fichier.
sed
retourne dans son code de sortie la valeur numérique ou 1 en fonction de la possibilité ou non de la trouver l'expression rationnelle adressée.
$i
est défini sur sed
's s return on exit.
Le groupement {
; }
est utilisé pour gérer de manière robuste toute erreur de redirection possible - $i
n'est pas défini dans le cas où le shell ne peut pas ouvrir le fichier, évitant ainsi les faux positifs.
Ceci ne devrait probablement pas être préféré à grep -q
, cependant, ce qui peut fondamentalement aussi faire tout ce qui précède ((si inverse), faites-le POSIXly et généralement plus rapidement.
La réponse grep -q
déjà donnée est très bonne, mais un petit doute:
grep -q pattern ./infile; i=$((!$?))
Vous pouvez utiliser ceci:
#!/bin/bash
while IFS= read -r line; do
case "$line" in *::=BEGIN*) i=1 && break;;
*) i=0
esac
done <file.txt
Ceci recherchera le fichier file.txt
ligne par ligne et si une correspondance de ::=BEGIN
est trouvée, il définira la variable i=1
et se fermera. Si aucune correspondance n'est trouvée, la variable sera définie sur i=0
.
Ma version sed
name__
sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}'
à stocker dans une variable i
name__:
i=$(sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}')
Exemple:
$ echo "::=BEGIN" > foo
$ echo "::=BEGIN" >> foo
$ sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}'
1
$ echo "::=NOT_BEGIN" > foo
$ sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}'
0
$ echo "::=BEGIN" >> foo
$ sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}'
1
Explication:
::=BEGIN
est trouvé, imprimez un 1
et passez à next
name__::=BEGIN
est introuvable, imprimez 0
sed
(Stream Editeur) n'est pas l'outil idéal pour ce genre de choses: vous pouvez simplement utiliser une instruction bash
if
pour faire correspondre votre entrée à une expression régulière:
#!/bin/bash
#...
input="$(< inputfile)"
[[ "$input" =~ ::=BEGIN ]] && i=1 || i=0
#...
input="$(< inputfile)"
: assigne le contenu de inputfile
à la variable $input
[[ "$input" =~ ::=BEGIN ]] && i=1 || i=0
: fait correspondre la regex ::=BEGIN
au contenu de la variable $input
; s'il y a correspondance, il attribue 1
à $i
, sinon il attribue 0
à $i