Vérifier la présence d'un mot dans une ligne
RésoluDecon Messages postés 95 Statut Membre -
Je voudrais savoir comment parcourir un fichier et tester pour chaque ligne s'il contient un mot donné afin d'exécuter un script particulier lorsqu'elle contient le mot.
En shell bourne.
Merci d'avance.
11 réponses
Il s’agit de parcourir un fichier ligne par ligne et de tester, pour chaque ligne, la présence d’un mot donné afin d’exécuter un script en shell bourne. Plusieurs réponses proposent d’utiliser une boucle while read line et d’extraire le code (par exemple .2-29 ou .2-30) via egrep -o, puis d’employer un case pour lancer les tâches. Des difficultés apparaissent, notamment des erreurs de substitution sous /bin/sh, des EOF en lecture et des erreurs de syntaxe liées à l’usage de ici-strings ou de constructions bash. En pratique, une approche portable évite ici-strings et constructions propres à bash, et traite les lignes avec des pipelines simples pour obtenir une solution POSIX sous /bin/sh.
-
Salut,
while read ligne do grep -q 'motif' <<<${line} if [ "$?" -eq "0" ] then blablabla else blablabla fi done < fichier
Mais bon, ça reste très schématique et sûrement pas adapté à 100% à ton cas ;-((
-
J'ai une erreur à chaque fois.[CODE]syntax error at line n°: '<' unexpected[/CODE]
C'est un script sh que j'exécute. -
Désolé, voici le code:
#liste les logs du plus recent au plus ancien find /InstancesArbor/CATDEV3/KBP_APPLI/y/log \( -name 'Nom.0.2-29*.*.log' -o -name 'Nom.0.2-3[0-9]*.*.log' \) -ls | grep -v 'Nom.0.2-29.core_bp_duct_educt.*.log' | sort -r -n -t. +3 > tmp.file while read ligne do grep -q 'Nom.0.2-29.2*.log' <<<${line} if [ "$?" -eq "0" ] then echo "blabla" fi done < tmp.file
Aussi, est-ce possible de mettre le grep à l'intérieur du if, parce que j'ai l'impression que le code actuel me permet de tester la présence que d'un mot; alors que je veux en tester plusieurs avec pour chacun une action spéciale. -
tmp.file contient :
-rw-rw-r-- 1 arbdev3 arboradm 7679 May 2 11:53 Nom.0.2-30.20110502.115217.log -rwxr-xr-x 1 arbdev3 arboradm 15647 May 2 11:45 Nom.0.2-29.20110502.114254.log -rwxr-xr-x 1 arbdev3 arboradm 15698 May 2 11:01 Nom.0.2-29.20110502.105858.log -rwxr-xr-x 1 arbdev3 arboradm 3622 Apr 29 17:31 Nom.0.2-30.20110429.173020.log -rwxr-xr-x 1 arbdev3 arboradm 13596 Apr 14 13:05 Nom.0.2-29.20110414.130358.log -rwxr-xr-x 1 arbdev3 arboradm 5650 Apr 14 13:02 Nom.0.2-30a.20110414.130157.log -rwxr-xr-x 1 arbdev3 arboradm 5636 Apr 14 13:01 Nom.0.2-30.20110414.130115.log
J'ai mis -Eq et "" à la place de '', j'ai un message: Illégale option -E , -q-
-
-
Dans ton exemple (grep -q 'Nom.0.2-29.2*.log') le but était bien de matche les 3 lignes sus-citées quand même non ? ;-\
Donc à partir de là :
$ egrep 'Nom.0.2-29.*.log' plop -rwxr-xr-x 1 arbdev3 arboradm 15647 May 2 11:45 Nom.0.2-29.20110502.114254.log -rwxr-xr-x 1 arbdev3 arboradm 15698 May 2 11:01 Nom.0.2-29.20110502.105858.log -rwxr-xr-x 1 arbdev3 arboradm 13596 Apr 14 13:05 Nom.0.2-29.20110414.130358.log $ egrep 'Nom.0.2-30.*.log' plop -rw-rw-r-- 1 arbdev3 arboradm 7679 May 2 11:53 Nom.0.2-30.20110502.115217.log -rwxr-xr-x 1 arbdev3 arboradm 3622 Apr 29 17:31 Nom.0.2-30.20110429.173020.log -rwxr-xr-x 1 arbdev3 arboradm 5650 Apr 14 13:02 Nom.0.2-30a.20110414.130157.log -rwxr-xr-x 1 arbdev3 arboradm 5636 Apr 14 13:01 Nom.0.2-30.20110414.130115.log $
etc.
;-)) -
je vois ce que tu veux dire; mais les lignes du fichier tmp.file sont déjà dans un certains ordre et l'exécution des tâches associées à chaque ligne doit se faire dans ce même ordre. C'est pour cela que je ne souhaite pas ramener toutes les lignes contenant 29, puis 30, ..
Ce que je veux faire c'est de parcourir dans l'odre le fichier et exécuter les tâches dans ce même ordre.
J'espère avoir été un peu plus clair. -
Ok. Un exemple avec dans le fichier "plop" le contenu de ton exemple plus haut...
$ cat foo.sh #! /bin/bash while read line do A=$(egrep -o '\.2-..' <<<${line}) case ${A} in .2-29) echo "${line##* } contient 29" ;; .2-30) echo "${line##* } contient 30" ;; esac done < plop $ ./foo.sh Nom.0.2-30.20110502.115217.log contient 30 Nom.0.2-29.20110502.114254.log contient 29 Nom.0.2-29.20110502.105858.log contient 29 Nom.0.2-30.20110429.173020.log contient 30 Nom.0.2-29.20110414.130358.log contient 29 Nom.0.2-30a.20110414.130157.log contient 30 Nom.0.2-30.20110414.130115.log contient 30 $
-
-
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question -
Merci de ton aide,
En revanche, es tu sûr que ça fonctionne de la même manière en bin/sh, parce que j'ai le message d'erreur:syntax error at line 32: 'A=$' unexpected
Voici mon code complet#!/bin/sh #Vérification des patchs installés #***************************************************** #liste les logs du plus recent au plus ancien find /InstancesArbor/CATDEV3/KBP_APPLI/y/log \( -name 'Nom.0.2-29*.*.log' -o -name 'Nom.0.2-3[0-9]*.*.log' \) -ls | grep -v 'Nom.0.2-29.core_bp_duct_educt.*.log' | sort -r -n -t. +3 > tmp.file while read line do A=$(egrep -o '\.2-..' <<<${line}) case ${A} in .2-29) echo "${line##* } contient 29" ;; .2-30) echo "${line##* } contient 30" ;; esac done < tmp.file -
-
find /InstancesArbor/CATDEV3/KBP_APPLI/y/log \( -name 'Nom.0.2-29*.*.log' -o -name 'Nom.0.2-3[0-9]*.*.log' \) -ls | grep -v 'Nom.0.2-29.core_bp_duct_educt.*.log' | sort -r -n -t. +3 > tmp.file + find /InstancesArbor/CATDEV3/KBP_APPLI/y/log ( -name Nom.0.2-29*.*.log -o+ -namesort Nom.0.2-3[0-9]*.*.log ) -r -ls+ -n grep -t.-v +3NEUF_TELECOM_CEG_ENT_BP12.0.2-29.core_bp_duct_educt.*.log while read line do #A=$(grep -o '\.2-..' <<<${line}) A=$(etest.sh: syntax error at line 9: 'A=$' unexpected -
Le message d'erreur a changé. Maintenant j'ai:
egrep: illegal option -- o usage: egrep [ -bchilnsv ] [ -e exp ] [ -f file ] [ strings ] [ file ] ...
-
Je l'ai fais. Il me renvoie l'erreur "bas substitition" quand je le fais sous bin/sh; mais en mettant bin/bash, ça marche.
Suis je obligé de le faire sous bash, Parce qu'en réalité, mon script est beaucoup plus long et le reste s'exécute avec sh.-
"bad substitution"
Faudrait savoir ce qu'il n'aime pas ;-\
A mon avis c'est les "${A##*-}" et les "${line##* }"
Essaie comme ça :
#! /bin/sh while read line do A='echo ${line} | egrep '\.2-..'' A='echo ${A} | awk -F'-' '{print $NF}'' case ${A} in 29*) echo "${line} contient 29" ;; 30*) echo "${line} contient 30" ;; esac done <tmp.file
-
-
Ca marche!!!
SUPER MERCI.
T'es trop sympa.
Je ne sais pas comment te dire merci; mais MERCi tout simplement. -
Bonjour,
Je reviens suite à un problème de EOF que je rencontre; notament le message suivant lors du parcours de mon fichier par le read line:** ERROR ** EOF encountered while reading standard in. Now exiting...