Forum |  HardWare.fr | News | Articles | PC | Prix | S'identifier | S'inscrire | Aide | Shop Recherche
565 connectés 

  FORUM HardWare.fr
  Linux et OS Alternatifs
  Codes et scripts

  [Shell] grep - afficher que la première occurence trouvée?

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Shell] grep - afficher que la première occurence trouvée?

n°279386
duch
Posté le 18-06-2003 à 11:06:43  profilanswer
 

Salut,
 
En complément de spamassassin, qui est pour rappel un progamme qui filtre les spams et que j'ai réglé pour stocker les spams dans un répertoire nommé /var/spool/spam, j'ai écrit une petite ligne de commande qui extrait les lignes Subject des fichier stockés et les ajoute à un rapport (pour faciliter la vérification):
 
cat out.* | grep 'Subject:' > report.txt
 
le problème c'est que dans chaque fichier out. la ligne Subject: apparait 2 fois.
 
Comment faire donc pour n'écrire que la première occurence?
 
au passage, si quelqu'un sait comment faire pour ajouter le nom du fichier dans le rapport, je suis preneur...

mood
Publicité
Posté le 18-06-2003 à 11:06:43  profilanswer
 

n°279388
minusplus
Posté le 18-06-2003 à 11:12:05  profilanswer
 

(1) cat out.* | grep 'Subject' | tail -1 > report.txt
(2) for i in out.*; do echo -n "$i : " >> report.txt && cat $i | grep 'Subject' | tail -1 >> report.txt; done

n°279390
duch
Posté le 18-06-2003 à 11:15:10  profilanswer
 

merci minusplus, la première commande ne me sors que l'occurence du dernier fichier...
 
mais la deuxième marche nickel :D
 
bien qu'elle soit un peu longue à éxecuter...


Message édité par duch le 18-06-2003 à 11:17:28
n°279439
arsunik
ma tuxitude me beastifie
Posté le 18-06-2003 à 12:05:35  profilanswer
 

Le cat ne sert à rien.
Il suffit de faire "grep chaine fichier" (et puis comme ça ça t'affichera le nom du fichier).
Si la ligne "Subject:" est identique, tu peux utiliser uniq pour la supprimer :
 
grep 'Subject:' out.* | uniq

n°279442
duch
Posté le 18-06-2003 à 12:07:02  profilanswer
 

merci pour la précision pour uniq.
 
Le cat me sert car je crér un nouveau fichier qd même...

n°279549
kazekami
J'aime pas les gens
Posté le 18-06-2003 à 14:53:48  profilanswer
 

duch a écrit :

Le cat me sert car je crér un nouveau fichier qd même...


 
oui, et ?  
 
sinon je pense que tu peux faire un
 
(grep 'Subject:' out.* | head -n 1) > report.txt


---------------
Self Destruction Might Be The Answer - http://www.kazekami.org
n°279550
houplaboom​42
Posté le 18-06-2003 à 14:56:37  profilanswer
 

KazeKami a écrit :


 
oui, et ?  
 
sinon je pense que tu peux faire un
 
(grep 'Subject:' out.* | head -n 1) > report.txt


 
EDIT: http://rhols66.adsl.netsonic.fi/era/unix/award.html


Message édité par houplaboom42 le 18-06-2003 à 15:02:14
n°279551
kazekami
J'aime pas les gens
Posté le 18-06-2003 à 14:57:21  profilanswer
 


 
not found :/


---------------
Self Destruction Might Be The Answer - http://www.kazekami.org
n°279553
houplaboom​42
Posté le 18-06-2003 à 15:01:50  profilanswer
 
n°279558
duch
Posté le 18-06-2003 à 15:08:00  profilanswer
 

KazeKami >
 
merci beacoup pour la précision, j'ai pô tout compris mais j'vais regardé :D
 
mais comment tu fais pour boucler sur tous les fichiers?


Message édité par duch le 18-06-2003 à 15:13:25
mood
Publicité
Posté le 18-06-2003 à 15:08:00  profilanswer
 

n°279570
kazekami
J'aime pas les gens
Posté le 18-06-2003 à 15:17:38  profilanswer
 

duch a écrit :

KazeKami >
 
merci beacoup pour la précision, j'ai pô tout compris mais j'vais regardé :D
 
mais comment tu fais pour boucler sur tous les fichiers?


 
effectivement je suis fatigué, j'ai pas fait attention que tu faisais ca sur out.* :mrgreen:
 
la solution de -/+ est bien en fait :whistle:


---------------
Self Destruction Might Be The Answer - http://www.kazekami.org
n°279598
duch
Posté le 18-06-2003 à 16:13:45  profilanswer
 

arf! :p

n°279641
minusplus
Posté le 18-06-2003 à 17:19:19  profilanswer
 

:sol:

n°280029
duch
Posté le 19-06-2003 à 10:27:39  profilanswer
 

je vous mets une nouvelle fois à contribution pour améliorer un poil le script...
 
j'aimerais renommer tous les fichiers de la forme out.* en out.*.reported (ça je sais faire), mais ce que je ne sais pas faire c'est ignorer les fichiers du type out.*.reported lorsque je crée le rapport (le but est de les appeler .reported pour les ignorer le prochain coup)
 
j'ai essayé ça :
 

Code :
  1. for i in /var/spool/spam/out.* | grep -v reported; do echo -n "$i : " >> /var/spool/filter/report.txt && cat $i | grep 'Subject' | tail -1 >> /var/spool/filter/report.txt && cat $i | grep 'Content analysis details' >> /var/spool/filter/report.txt; done
  2. for i in /var/spool/spam/out.*; do mv $i $i.reported; done


 
la deuxième ligne qui renomme les fichiers marche évidemment mais il encaisse pas le grep dans la première...
 
il y a sans doute une syntaxe particulière dans le cas d'un for in mais j'la connais pô :(


Message édité par duch le 19-06-2003 à 10:29:08
n°280056
minusplus
Posté le 19-06-2003 à 10:51:10  profilanswer
 

ça :


for i in /var/spool/spam/out.* | grep -v reported; do echo -n "$i : " >> /var/spool/filter/report.txt


ça va pas. ce que tu veux faire, c'est ça :


for i in $(ls /var/spool/spam/out.* | grep -v reported); do echo -n "$i : " >> /var/spool/filter/report.txt


mais c'est moche. Dans ton cas vaut mieux utiliser find :


find -name "out.*" ! -name "*.reported" -exec echo "{} :" >> /var/spool/filter/report.txt && cat "{}" | grep Subject | head -1 >> /var/spool/filter/report.txt && mv "{}" "{}".reported \;  

n°280058
minusplus
Posté le 19-06-2003 à 10:52:43  profilanswer
 

ou plus court :


find -name "out.*" ! -name "*.reported" -exec echo "{} : $(cat {} | grep Subject | head -1 )" >> /var/spool/filter/report.txt && mv "{}" "{}".reported \;  


 
 
 
tout ceci est à tester, hein ! :D

n°280060
duch
Posté le 19-06-2003 à 10:55:29  profilanswer
 

arf
 
j'étais pas très loin, même si c'était moche :D
 
j'vais tester...
 
j'avais aussi ajouter ces 2 lignes ensuite mais j'suppose qu'on peux faire mieux :
 
echo "nombre de spams :" >> /var/spool/filter/report.txt
echo ls /var/spool/spam/out.* | grep -c reported >> /var/spool/filter/report.txt
 
(je ne sais notamment pas comment les ajouter au début du fichier) qui a dit newbie?

n°280061
duch
Posté le 19-06-2003 à 11:02:20  profilanswer
 

j'ai testé la première méthode, car j'avais d'autres lignes à ajouter et je ne voyais pas très bien comment faire.
 
je suis donc arriver à ça :
 

Code :
  1. find -name "out.*" ! -name "*.reported" -exec echo "{} :" >> /var/spool/filter/report.txt && cat "{}" | grep Subject | head -1 >> /var/spool/filter/report.txt && cat "{}" | grep 'Content analysis details' >> /var/spool/filter/report.txt && mv "{}" "{}".reported \;


 
et j'obtiens :
 
paramètre manquant pour exec...
 
j'ai fait un man exec (en fait execve) et les parmaètres à mettre sont :
 
 int execve (const char *filename, char *const argv [], char *const envp[]);
 
 
comprends pô tout môa...
 
PS : j'ai essayé aussi sans toucher à ta ligne et ça marche pô non plus :(


Message édité par duch le 19-06-2003 à 11:03:16
n°280065
minusplus
Posté le 19-06-2003 à 11:12:26  profilanswer
 

ha ui pardon ! :o
 


 
  find -name "out.*" ! -name "*.reported" -exec bash -c 'echo "{} :" >> /var/spool/filter/report.txt && cat {} | grep Subject | head -1 >> /var/spool/filter/report.txt && cat {} | grep 'Content analysis details' >> /var/spool/filter/report.txt && mv {} {}.reported' \;

n°280077
duch
Posté le 19-06-2003 à 11:34:22  profilanswer
 

bah en fait y'a plus d'erreur mais il ne crée pas le fichier report.txt :(
 
il ne manquerait pas le chemin pouyr accéder au fichiers out.* par hasard?
 
j'ai essayé ça sans résultat :
 

Code :
  1. find -name "/var/spool/spam/out.*" ! -name "/var/spool/spam/*.reported" -exec bash -c 'echo "{} :" >> /var/spool/filter/report.txt && cat {} | grep Subject | head -1 >> /var/spool/filter/report.txt && cat {} | grep 'Content analysis details' >> /var/spool/filter/report.txt && mv {} {}.reported' \;


n°280083
duch
Posté le 19-06-2003 à 11:45:14  profilanswer
 

bon en fait après lecture de man find, ça serait plutôt ça :
 

Code :
  1. find -path "/var/spool/spam" -name "out.*" ! -name "*.reported" -exec bash -c 'echo "{} :" >> /var/spool/filter/report.txt && cat {} | grep Subject | head -1 >> /var/spool/filter/report.txt && cat {} | grep 'Content analysis details' >> /var/spool/filter/report.txt && mv {} {}.reported' \;


 
mais ça marche toujours pô, faut-il spécifier deux fois -path?
 
l'erreur est la suivante :
 
./spamreport: /var/spool/filter/report.txt: Aucun fichier ou répertoire de ce type
 
et elle survient à cette ligne :
 

Code :
  1. mail -s "filtre anti-spam" xxx@xxx.com < /var/spool/filter/report.txt


 
ce qui veux dire que le fichier report.txt n'a pas été crée.


Message édité par duch le 17-05-2004 à 09:54:33
n°280118
minusplus
Posté le 19-06-2003 à 12:43:54  profilanswer
 

ben je sais pas, t'as les droits d'écriture dans /var/spool/filter ?

n°280120
duch
Posté le 19-06-2003 à 12:45:54  profilanswer
 

bah ouais je teste en root.
 
et puis avec l'autre version du script (avec le for) ça marche nickel, j'comprends pô.
 
même qd je fais

Code :
  1. find -path "/var/spool/spam" -name "out.*"

ça renvois rien...
 
c'est bien comme ça qu'on passe le path?

n°280122
minusplus
Posté le 19-06-2003 à 12:47:27  profilanswer
 

fais voir un 'ls /var/spool/spam' ? :D

n°280126
duch
Posté le 19-06-2003 à 12:57:34  profilanswer
 

:D
 

Code :
  1. icilalune:/etc/apache# ls /var/spool/spam
  2. out.20638


Message édité par duch le 19-06-2003 à 12:57:47
n°280459
duch
Posté le 19-06-2003 à 22:40:25  profilanswer
 

bon come la directive -path ne marche pô j'ai "rusé" :
 

Code :
  1. cd /var/spool/spam/
  2. find -name "out.*" ! -name "*.reported" -exec bash -c 'echo "{} :" >> ../filter/report.txt && cat {} | grep Subject | head -1 >> ../filter/report.txt && cat {} | grep 'Content analysis details' >> ../filter/report.txt && mv {} {}.reported' \;


 
comme ça, ça marche :D
 
par contre qd je lance le script, il m'affiche tout le contenu des mails dans la console... y'a pas un mode -quiet? (en même temps j'men fous car le script est lancé avec cron mais c'est pas clean)
 
 
autre question (et pis après c'est fini), j'trouve pas comment on écrit au début d'un fichier? ça doit être un truc avec l'opérateur > mais une recherche dans google c'est pô facile...

n°280532
duch
Posté le 20-06-2003 à 09:52:28  profilanswer
 

en fait non ça ne marche pô, enfin partiellement
 
voici mon script simplifié :
 

Code :
  1. cd /var/spool/spam/
  2. find -name "out.*" ! -name "*.reported" -exec bash -c 'echo "{} :" >> report.txt && cat {} | grep Subject | head -1 >> report.txt && cat {} | grep 'Content analysis details' >> report.txt && mv {} {}.reported' \;
  3. echo "nombre de spams :" >> report.txt
  4. echo ls out.* | grep -c reported >> report.txt
  5. mail -s "filtre anti-spam" xxx@xxx.com < report.txt
  6. rm report.txt


 
les problèmes sont les suivants :
 
il ne fait pas le mv
donc à chaque que je lance le script, il retraite tous les fichiers
donc echo ls out.* | grep -c reported >> report.txt renvoie 0 (ça c'est pas très grave)
et en plus quand je lance le script il me sort le contenu des mails dans la console :(
 
 
rectification :
 
il ne fait ni le mv ni la seconde commande cat, en fait c'est comme si il ne faisait que ça :
 

Code :
  1. find -name "out.*" ! -name "*.reported" -exec bash -c 'echo "{} :" >> report.txt && cat {} | grep Subject | head -1 >> report.txt


Message édité par duch le 17-05-2004 à 09:54:49
n°1380667
nitneuc86
Posté le 04-09-2015 à 21:34:28  profilanswer
 

Bonjour
 

Code :
  1. $ printf "aaa\naaa\naaa\n"| grep --max-count=1 "aaa"


 
Cette commande ne renverra que la première occurence de "aaa"
 
Le commutateur

--max-count=X

correspond à

-m X

n°1380670
black_lord
Modérateur
Truth speaks from peacefulness
Posté le 04-09-2015 à 21:43:28  profilanswer
 

up de 12 ans, surement un record


---------------
uptime is for lousy system administrators what Viagra is for impotent people - mes unixeries - github me
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Linux et OS Alternatifs
  Codes et scripts

  [Shell] grep - afficher que la première occurence trouvée?

 

Sujets relatifs
Installer une imprimante via le shell , c possible ?[bash] faire un rm de " ls | grep -E "^[1-9]{1,2} "
[Gentoo] Premiere instalationRed hat, je n'ai pas de shell!
[Shell] Recuperer la ligne n d'un fichier ?[Shell] Recuperer le 3eme mot d'une ligne ??
shell : comment virer le signe "degre" d une chaine ??[challenge debile] Un cat pour deux grep....
[Shell] C'est quoi la syntaxe du switch (case) :??:Fenêtre shell tjrs ouverte et "incrustée" au fond d'écran ?
Plus de sujets relatifs à : [Shell] grep - afficher que la première occurence trouvée?


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite) / Groupe LDLC / Shop HFR