|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 |
|
Candidat au titre de Membre du Club
![]() Inscription : février 2008 Messages : 96 ![]() |
Bonsoir,
J'ai un fichier dans lequel j'ai déjà filtré les enregistrements que je souhaitais via un sed -n. Exemple : Code :
cat $fic | sed -n '/30076/p' | sed -n '/2019/p' > $fictmp Soit je récupère ma valeur qui se trouve toujours en position 5 sur 6 caractères et je substitue celle-ci par ma varibale que j'ai passé en paramètre (mais cela est très lourd vu le nombre de lignes de mes fichiers en entrée, et en plus cela ne fonctionne pas parfaitement), soit je ne travaille plus ligne par ligne, mais sur tout le fichier $fictmp et je lui demande de modifier les valeurs de la position 5 à 10 par celle du paramètre. Savez vous comment faire cela ? Merci |
|
|
01
|
|
|
#2 |
|
Expert Confirmé Sénior
![]() francois Ingénieur systèmes et réseaux Inscription : juillet 2006 Messages : 3 534 ![]() |
Code :
cat $fic | sed -n '/30076/p' | sed -n '/2019/p' > $fictmp Code :
sed -n '/30076|2019/p' $fic > $fictemp |
|
|
00
|
|
|
#3 | |||
|
Expert Confirmé
![]() Inscription : janvier 2011 Messages : 970 ![]() |
Salut,
Citation:
Code :
Code :
sed -n '/30076/p' $fic | sed -n '/2019/p' et qu'on pourrait réduire à : Code :
sed -n '/30076.*2019\|2019.*30076/p' $fic Si toutefois on recherche à la fois une ligne contenant "30076" ET "2019" dans n'importe quel ordre... Mais je le répète, j'ai peut être mal interprété la demande et dans ce cas là j'ai tout faux (ou presque, la protection du pipe étant exacte), et je m'en excuse par avance
__________________
$ man woman Il n'y a pas de page de manuel pour woman. |
|||
|
|
20
|
|
|
#4 | ||
|
Candidat au titre de Membre du Club
![]() Inscription : février 2008 Messages : 96 ![]() |
Merci bien.
Ca va me permettre d'optimiser. Mais si j'ai d'autres "couples" de valeurs à chercher dans mes enregistrements, est-il préférable de rajouter des lignes tel que : Code :
Code :
sed -n '/30076|30080|2020|2022/p' $fic >> $fictemp Car maintenant je suis sur la ligne et non sur la totalité du fichier. Je veux remplacer la valeur existante de la position 5 à 10 incluse par celle amenée en paramètre yyyymm. Si j'ai la valeur 201012 (dans mon fichier pos 5 à 10) et qu'en paramètre j'ai mis 201105, il me faut dans tout le fichier mettre 201105. Merci bien. |
||
|
|
10
|
|
|
#5 |
|
Expert Confirmé
![]() Inscription : janvier 2011 Messages : 970 ![]() |
Attention de bien relire les explications au-dessus concernant la protection du "pipe" avec "sed".
Pour les couples il faut utiliser la syntaxe (utilisation de l'option "-r", puis des parenthèses et des pipes) : Code :
sed -nr '/(30076.*30080|30080.*30076)|(2020.*2022|2022.*2020)/p' $fic Pour le reste de ta demande un exemple concret serait le bienvenu
__________________
$ man woman Il n'y a pas de page de manuel pour woman. |
|
|
20
|
|
|
#6 |
|
Candidat au titre de Membre du Club
![]() Inscription : février 2008 Messages : 96 ![]() |
je viens de tester cela :
ou Mais cela ne fonctionne pas. 1er cas : résultat NULL 2ème cas : message d'erreur |
|
|
02
|
|
|
#7 |
|
Membre Expert
![]() |
|
|
|
20
|
|
|
#8 | ||
|
Expert Confirmé
![]() Inscription : janvier 2011 Messages : 970 ![]() |
Quel système ?
Quelle distrib ? Quelle version de "sed" ? On peut avoir un bout de ton fichier histoire qu'on teste de notre côté... Un exemple où on cherche "toto suivi de tata ou tata suivi de toto" ou "tutu suivi de tyty ou tyty suivi de tutu" : Code :
__________________
$ man woman Il n'y a pas de page de manuel pour woman. |
||
|
|
20
|
|
|
#9 | |
|
Expert Confirmé Sénior
![]() francois Ingénieur systèmes et réseaux Inscription : juillet 2006 Messages : 3 534 ![]() |
Citation:
|
|
|
|
10
|
|
|
#10 | ||
|
Candidat au titre de Membre du Club
![]() Inscription : février 2008 Messages : 96 ![]() |
La version du système :
SunOS devece 5.10 Generic_142900-03 sun4u sparc SUNW,Sun-Fire-15000 Je suis en ksh. Pour la version de sed, je ne sais pas où trouver cela. Un bout du fichier : Code :
Seule la ligne avec les valeurs en gras sera sélectionnée dans cet exemple. |
||
|
|
01
|
|
|
#11 | ||
|
Membre Expert
![]() |
Ca nous va parfaitement, maintenant, que cherches-tu à faire exactement ?
Si j'ai bien compris ton premier post, tu veux trouver les lignes qui contiennent 30076 et 2019. Et ensuite, tu veux remplacer les 6 caractères en position 5 (qui correspondent à une date au format YYYYMM) par d'autres caractères ? En perl, ça donnerait ceci: Code :
perl -ple 'substr($_,4,6)="201104" if (/64510/ && /2002/);' test > test2 L'option -l indique que pour traiter chaque ligne, on retire déjà le symbole fin de ligne s'il est présent à la fin de la ligne, et qu'après avoir affiché la ligne, on ajoute à nouveau le symbole de fin de ligne (très utile pour contourner les problèmes de fin de ligne entre les OS et pour éviter d'être ennuyé par les sauts de lignes). L'option -e indique que ce qui suit entre quote est le traitement à appliquer entre la lecture de la ligne et son affichage. Explication du traitement : if (/30076/ && /2019/) signifie "si la ligne contient 64510 et 2002" substr($_,4,6)="201104" remplace le contenu de $_ (qui contient la ligne) à partir de la position 5 (4 compté à partir de 0) et sur 6 caractères par 201104. Comme cette commande est suivie du if précédent, ça ne fait la manipulation que si la condition est remplie (si la ligne contient 30076 et 2019). J'ai modifié le critère de recherche car dans ton exemple, il n'y avait pas de ligne avec 30076 et 2019... donc j'ai pris 64510 et 2002 : Code :
|
||
|
|
11
|
|
|
#12 |
|
Candidat au titre de Membre du Club
![]() Inscription : février 2008 Messages : 96 ![]() |
Oui j'ai modifié par la suite une des lignes car les données étaient fausses.
En tout cas tu as parfaitement compris ce que je souhaite faire. Tu n'as pas d'autres moyens que le Perl. Ca m'est interdit ... |
|
|
01
|
|
|
#13 |
|
Membre Expert
![]() |
En awk alors ?
Code :
awk '{if (/64510/ && /2002/) { $0 = substr($0,1,4) "201104" substr($0,11) } print}' test > test3 if (/64510/ && /2002/) idem que perl $0 = substr($0,1,4) "201104" substr($0,11) on modifie $0 qui contient la ligne complète en prenant les 4 premiers caractères, concaténés à 201104 puis la fin de la ligne depuis le caractère 11 |
|
|
11
|
|
|
#14 | |||
|
Candidat au titre de Membre du Club
![]() Inscription : février 2008 Messages : 96 ![]() |
Est-ce que cela donnerait un shell tel que celui-ci :
Code :
Citation:
|
|||
|
|
02
|
|
|
#15 | ||||
|
Membre Expert
![]() |
1) Il vaut mieux tester la présence de paramètre avant de faire l'association:
Code :
devient 3) awk permet de faire grosso modo la même chose que sed (avec plus d'options), donc pas la peine de multiplier les appels à sed + awk dans un script 4) pas la peine non plus de multiplier les fichiers si ça n'est pas indispensable En partant de ces différents points, et en supposant qu'il n'est pas non plus indispensables de supprimer l'extension de tes fichiers de départs pour les remplacer par un .old (ce qui est risqué si tu as 2 fichiers de même nom mais d'extension différente), voici un script qui devrait marcher : Code :
Ensuite, je lance la commande awk sur le fichier renommé en redirigeant la sortie vers le fichier d'origine. Dans l'exemple ci-dessus, je n'ai recopié que 2 des 6 critères que tu avais mis dans ton sed, et j'en ai mis un 3ème pour passer sur mes fichiers de test. Tu devrais pouvoir rajouter les critères dont tu as besoin Edit : en plus, tes critères peuvent être simplifiés (il y a un doublon, et les 4 derniers sont presque tous identiques à 1 chiffre prêt) : Code :
(30076.*2019)|<s>(10468.*2240)|</s>(10468.*2240)|(10468.*2245)|(10468.*2246)|(10468.*2247) |
||||
|
|
20
|
|
|
#16 | |
|
Candidat au titre de Membre du Club
![]() Inscription : février 2008 Messages : 96 ![]() |
Je vais tester cela ce matin et vous tiens au courant.
Merci encore pour votre aide. J'ai cela en résultat : Citation:
|
|
|
|
01
|
|
|
#17 | ||
|
Candidat au titre de Membre du Club
![]() Inscription : février 2008 Messages : 96 ![]() |
Maintenant je n'ai plus d'erreur car j'ai utilisé nawk au lieu de awk.
Mais aucun filtre ne se fait. Voici le script : Code :
|
||
|
|
10
|
|
|
#18 |
|
Candidat au titre de Membre du Club
![]() Inscription : février 2008 Messages : 96 ![]() |
la commande doit-être ainsi avec notre awk :
Code :
nawk '{if (/30076.*2019/ || /10468.*224[0567]/) {print substr($0,1,4) ${idmois} substr($0,11)} }' $ficold > $fic Le filtre fonctionne uniquement si je ne mets pas la commande substr($0,1,4) ${idmois} substr($0,11) il n'a pas l'air de reconnaitre idmois dans cette commande awk. |
|
|
11
|
|
|
#19 | |
|
Expert Confirmé
![]() Inscription : janvier 2011 Messages : 970 ![]() |
Citation:
Soit : Code :
nawk '{if (/30076.*2019/ || /10468.*224[0567]/) {print substr($0,1,4) '"${idmois}"' substr($0,11)} }' $ficold > $fic
Code :
nawk -v IDMOIS=${idmois} '{if (/30076.*2019/ || /10468.*224[0567]/) {print substr($0,1,4) IDMOIS substr($0,11)} }' $ficold > $fic
__________________
$ man woman Il n'y a pas de page de manuel pour woman. |
|
|
|
20
|
|
|
#20 |
|
Candidat au titre de Membre du Club
![]() Inscription : février 2008 Messages : 96 ![]() |
Exact.
C'est ce que j'avais réalisé par la suite. Il fallait donc utiliser une variable et puis Nickel. J'avais une autre question mais là c'est pour compresser mes fichiers qui sont dans ma liste car sinon notre filesystem sera plein. Peut-être dois-je ouvrir un autre sujet ? En tout cas merci à tous pour cette aide. Ciao. |
|
|
01
|
Copyright © 2000-2012 - www.developpez.com