Selection ligne suivante CSH foreach

Résolu/Fermé
visiteurr - 2 févr. 2011 à 12:48
 visiteurr - 10 févr. 2011 à 08:25
Bonjour,


Je travail sous le Shell CSH, dans un parcour de fichier je souhaite comparer l'élément de la premiere colone ligne N avec l'element de la premiere colone ligne N+1. Je n'y arrive pas ... :/
Comment récuperer un element a N+1 ?

en Gro j'ai un fichier du type

simon ok x
simon ok x
simon ok x
simon ok x
fabien ok x
fabien ok x
seb ok x
yoann ok x
yoann ok x
yoann ok x
yoann ok x
yoann ok x
yoann ok x

et je veu obtenir ca :

simon ok 4
simon ok 4
simon ok 4
simon ok 4
fabien ok 2
fabien ok 2
seb ok 1
yoann ok 6
yoann ok 6
yoann ok 6
yoann ok 6
yoann ok 6
yoann ok 6

le fichier a traiter est trés grand par contre ... donc j'essai de faire quelque chose de léger ...


pour l'instant j'arrive a rien je test mais rien ne marche

ex :
#! /bin/csh -f

foreach line ( "'cat tttt'" )
set argv = ( $line )
set name1 = $1
set name2 = $3
if ( $1 == $1 + 1) then
echo " $1 et '$1+1' test true "
else
echo " $1 et 'expr $1 + 1' test false "
endif

end


voila si quelqu'un a une idée pour réaliser un tel script en CSH ... ( je suis nul en CSH mais bon j'ai pas choisi mon support de travail malheureusement :/ )

merci d'avance
A voir également:

11 réponses

zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 415
2 févr. 2011 à 14:29
Bon c'est pour un shell bash, il te faudra adapter la syntaxe pour le csh...

$ cat plop 
simon ok x febgeg
simon ok x rhedg
simon ok x erze
simon ok x srg e
fabien ok x nrteth
fabien ok x tehhet
seb ok x et ee
yoann ok x eth
yoann ok x et he
yoann ok x ehe
yoann ok x egr
yoann ok x ereh
yoann ok x ete

$ cat foo.sh 

#! /bin/bash

#set -xv

while read line
do
sed -i "/${line% *}/{s/ok x/ok ${line#* }/}" plop
done < <(awk '{ print $1 }' plop | uniq -c | awk '{ print $2,$1 }')


$ ./foo.sh 

$ cat plop 
simon ok 4 febgeg
simon ok 4 rhedg
simon ok 4 erze
simon ok 4 srg e
fabien ok 2 nrteth
fabien ok 2 tehhet
seb ok 1 et ee
yoann ok 6 eth
yoann ok 6 et he
yoann ok 6 ehe
yoann ok 6 egr
yoann ok 6 ereh
yoann ok 6 ete

$ 

;-))
2
Merci beaucoup c'est exactement ca que je veux faire !

Par contre j'arrive pas a le mettre en CSH :/ sachant que l'option -i de sed ne fonctionne pas en CSH :/

si quelqu'un connait le CSH et peu m'aider ? ( encore merci zipe31 )
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 415
2 févr. 2011 à 16:51
$ cat plop                        
simon ok x febgeg                                      
simon ok x rhedg                                       
simon ok x erze                                        
simon ok x srg e                                       
fabien ok x nrteth                                     
fabien ok x tehhet                                     
seb ok x et ee                                         
yoann ok x eth                                         
yoann ok x et he                                       
yoann ok x ehe                                         
yoann ok x egr                                         
yoann ok x ereh                                        
yoann ok x ete   

$ cat csh_foo.csh

#! /bin/csh

foreach line ( 'awk '{ print $1 }' plop | uniq -c | awk '{ printf "%s|%s\n",$2,$1 }'' )

set line = "$line:gas/|/ /"
set argv = ( $line )
sed "/$1/{s/ok x/ok $2/}" plop > blop
mv blop plop

end

$ ./csh_foo.csh

$ cat plop
simon ok 4 febgeg
simon ok 4 rhedg
simon ok 4 erze
simon ok 4 srg e
fabien ok 2 nrteth
fabien ok 2 tehhet
seb ok 1 et ee
yoann ok 6 eth
yoann ok 6 et he
yoann ok 6 ehe
yoann ok 6 egr
yoann ok 6 ereh
yoann ok 6 ete
$

;-))
2
RE Merci ^^
Il me renvoi ça : "Missing }"
rien d'autre c'est bizarre ... j'ai essayé de modifier ( remplacé les acolades etc ... mais rien ne marche ça fai tout le temps des erreurs.
Mais je comprend pas tu as fais ça sur une konsole en CSH alors pourquoi ca marche pas chez moi ? rrrr pourquoi j'ai jamais de chance avec l'informatique ? :/
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 415
3 févr. 2011 à 09:30
Re-

Il me renvoi ça : "Missing }"
rien d'autre c'est bizarre ... j'ai essayé de modifier ( remplacé les acolades etc ... mais rien ne marche ça fai tout le temps des erreurs.

Essaye de procéder petit à petit (c'est ce que j'ai fait hier, vu que le csh n'est pas ma tasse de thé et que j'avais des erreurs comme toi et notamment le fameux "Missing }" ;-((

Donc pour commencer :

#! /bin/csh

foreach line ( 'awk '{ print $1 }' plop | uniq -c | awk '{ printf "%s|%s\n",$2,$1 }'' )
echo $line
end

Et vois si tu as toujours des erreurs.

Attention toutefois, le code du forum interprète très mal les quotes inverses " ' " (Alt Gr + 7 le 7 du pavé alphanumérique celui au dessus des touches Y et U), donc dans l'expression :

foreach line ( 'awk '{ print $1 }' plop | uniq -c | awk '{ printf "%s|%s\n",$2,$1 }'' )

c'est bien une quote inversée avant le 1er awk et avant la dernière parenthèse fermante, hein ?



Mais je comprend pas tu as fais ça sur une konsole en CSH alors pourquoi ca marche pas chez moi ? rrrr pourquoi j'ai jamais de chance avec l'informatique ? :/
J'ai du l'installer hier sur une Mandriva 2010, ce n'est plus fourni par défaut, et à ce titre c'est du tcsh qui s'est installé, peut être est-ce du à cela ;-\

$ ls -l /bin/csh
lrwxrwxrwx 1 root root 4 2011-02-02 15:19 /bin/csh -> tcsh*

$ urpmq -fi tcsh
Name        : tcsh
Version     : 6.15
Release     : 6.4mdv2010.0
Group       : Shells
Size        : 616513                       Architecture: i586
Source RPM  : tcsh-6.15-6.4mdv2010.0.src.rpm
URL         : http://www.tcsh.org/
Summary     : An enhanced version of csh, the C shell
Description :
Tcsh is an enhanced but completely compatible version of csh, the C
shell.  Tcsh is a command language interpreter which can be used both
as an interactive login shell and as a shell script command processor.
Tcsh includes a command line editor, programmable word completion,
spelling correction, a history mechanism, job control and a C language
like syntax.
0
Ok merci encore, pour les quotes j'avai inversé :/ j'avai laissé le premier en normale et les autres a l'interieur en back :/ mais j'avai bien vu qu'il y'avai un souci ^^

je test ca et jte retient au courant.
0
humm alors aucun souci pour :
#! /bin/csh

foreach line ( 'awk '{ print $1 }' plop | uniq -c | awk '{ printf "%s|%s\n",$2,$1 }'' )
echo $line
end


ca marche très bien !

par contre quant je remet tout ( avec les bonnes quotes ^^ ) il met : Variable syntax
il y a qu'une variable je pense : $line et je voi pas pourquoi !

Comme tu as remarqué je suis très nul en CSH :/ désolé
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 415
3 févr. 2011 à 10:01
Essaie de supprimer les accolades dans l'expression avec sed :

sed "/$1/{s/ok x/ok $2/}" plop > blop
à transformer en :

sed "/$1/s/ok x/ok $2/" plop > blop
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 415
2 févr. 2011 à 13:18
Salut,

Au cas ou... des outils tous prêts existent sous GNU/Linux...

$ cat plop
simon ok x
simon ok x
simon ok x
simon ok x
fabien ok x
fabien ok x
seb ok x
yoann ok x
yoann ok x
yoann ok x
yoann ok x
yoann ok x
yoann ok x

$ uniq -c plop 
      4 simon ok x
      2 fabien ok x             
      1 seb ok x                
      6 yoann ok x    
          
$

;-))
0
merci bien pour ta réponse . Cependant ça compare les lignes et moi je ne veu comparer que la premiere colonne .
Car par exemple avec
simon ok x febgeg
simon ok x rhedg
simon ok x erze
simon ok x srg e
fabien ok x nrteth
fabien ok x tehhet
seb ok x et ee
yoann ok x eth
yoann ok x et he
yoann ok x ehe
yoann ok x egr
yoann ok x ereh
yoann ok x ete

ca ne marche pas :/

et c'est un fichier énorme donc le mieu serait de modifié directement :
Sachant que les lignes avec les premieres colone égale se suivent forcement (ouf)
Compter le nombre docurence du premier terme ( ex : simon ) puis metre en 3 eme colone ce nombre.

en gro:
L1 simon -> count = 1
L2 simon -> count = 2
L3 simon -> count = 3
L4 simon -> count = 4
L5 fabien -> count = 4 et on met 4 en 3eme colone de simon puis on remet count a 0

c'est en gro se que je veu faire...

mais sinon deja j'aimerai savoir : Comment récuperer un element a N+1 ? ( cf premiere question)

Grand merci
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
3 févr. 2011 à 20:05
Salut,

Cependant ça compare les lignes et moi je ne veu comparer que la premiere colonne .
Ben, pas pour moi.
D'après ce que je vois tu veux comparer les lignes mais juste sur un seul critère: le 1er mot de la ligne.
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
3 févr. 2011 à 20:09
Par exemple c'est ça que je vois

:~$ cat visiteurr 
simon ok x febgeg
simon ok x rhedg
simon ok x erze
simon ok x srg e
fabien ok x nrteth
fabien ok x tehhet
seb ok x et ee
yoann ok x eth
yoann ok x et he
yoann ok x ehe
yoann ok x egr
yoann ok x ereh
yoann ok x ete 
:~$ perl -ne 's/^(.*?)\s.*/$1. "-> count " . ($h{$1}++ + 1)/e;print' visiteurr
simon-> count 1
simon-> count 2
simon-> count 3
simon-> count 4
fabien-> count 1
fabien-> count 2
seb-> count 1
yoann-> count 1
yoann-> count 2
yoann-> count 3
yoann-> count 4
yoann-> count 5
yoann-> count 6
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
3 févr. 2011 à 20:13
:~$ cat visiteurr 
simon ok x febgeg
simon ok x rhedg
simon ok x erze
simon ok x srg e
fabien ok x nrteth
fabien ok x tehhet
seb ok x et ee
yoann ok x eth
yoann ok x et he
yoann ok x ehe
yoann ok x egr
yoann ok x ereh
yoann ok x ete 
:~$ perl -ne 's/^(.*?)\s(.*?)\sx(.*)/"$1 $2 " .($h{$1}++ + 1) . "$3"/e;print' visiteurr
simon ok 1 febgeg
simon ok 2 rhedg
simon ok 3 erze
simon ok 4 srg e
fabien ok 1 nrteth
fabien ok 2 tehhet
seb ok 1 et ee
yoann ok 1 eth
yoann ok 2 et he
yoann ok 3 ehe
yoann ok 4 egr
yoann ok 5 ereh
yoann ok 6 ete 
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
3 févr. 2011 à 21:20
Re,

Bon, il doit avoir plus simple mais je pense à quelque chose de genre :
- on obtiens le nombre d'occurrences et on les stocke dans un fichier temp

:~$ perl -ane '$h{$F[0]}++;END{print "$_:$h{$_}\n" for keys %h}' visiteurr > visiteurr.occ
lami20j@debian-acer:~$ cat visiteurr.occ 
seb:1
yoann:6
simon:4
fabien:2


- on utilise le fichier temp et on insère le nombre d'occurrences dans le fichier
:~$ cat visiteurr
simon ok x febgeg
simon ok x rhedg
simon ok x erze
simon ok x srg e
fabien ok x nrteth
fabien ok x tehhet
seb ok x et ee
yoann ok x eth
yoann ok x et he
yoann ok x ehe
yoann ok x egr
yoann ok x ereh
yoann ok x ete 
:~$ perl -ne '$h{$1}=$2 if /(.*):(.*)/;s/^(.*?)\s(.*?)\sx(.*)/$1 $2 $h{$1} $3/ and print' visiteurr.occ visiteurr
simon ok 4  febgeg
simon ok 4  rhedg
simon ok 4  erze
simon ok 4  srg e
fabien ok 2  nrteth
fabien ok 2  tehhet
seb ok 1  et ee
yoann ok 6  eth
yoann ok 6  et he
yoann ok 6  ehe
yoann ok 6  egr
yoann ok 6  ereh
yoann ok 6  ete 

0
bonjour,

Merci pour ta reponse lami20j ! heu par contre je ne connais pas ( et ne comprend pas ) le code que tu utilise ... c'est compatible CSH ?
Tu penses que le traitement est moins lourd avec cette commande ?
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 415
4 févr. 2011 à 11:46
Re-

Normalement Perl est installé sur tous les système GNU/Linux par défaut et ne dépend en rien du shell de connexion.

Il est aussi sensé être plus adapté à ce genre de traitement ;-))


PS. Je réponds à sa place sachant qu'il ne se connectera pas avant ce soir, sauf s'il veut me faire mentir ;-))
0
d'accord merci a vous 2 alors ^^ j'essai et je vous tien au courant :

( j'essai pas tout de suite vol vehicule = commissariat -> assurance etc ... :/ )
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 415
4 févr. 2011 à 11:50
Bon courage on compatit ;-\
0
oula lol j'ai rien modifier a par les noms de fichier et j'ai l'impression que ca marche ... je comrpend pas la lol

Où on selectionne la colonne a modifié ? pouvez vous m'expliquer cette commande ?
:~$ perl -ne '$h{$1}=$2 if /(.*):(.*)/;s/^(.*?)\s(.*?)\sx(.*)/$1 $2 $h{$1} $3/ and print' visiteurr.occ visiteurr
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
6 févr. 2011 à 10:20
Salut,


1ère commande

perl -ane '$h{$F[0]}++;END{print "$_:$h{$_}\n" for keys %h}' visiteurr > visiteurr.occ

Le rôle de cette commande c'est de compter le nombre d'occurrence du mot se trouvant au début des lignes du fichier.

Pour cela j'utilise la structure de donné appelée hash ou tableau associatif.
Cette structure de donnée permet d'accéder aux éléments de tableau par une clé (qui est une chaîne de caractère).
A chaque clé correspond une valeur (qui peut être une chaîne, un nombre, un tableau, un hash, une référence, bref un peu tout ;-)
Ce qui donne la présentation suivante

%hash = (
        "cle1" => "valeur",
        "cle2" => "autre valeur",
        ....
        "cleN" => "et encore une valeur",
);


A savoir que la clé est unique.

Dans ton exemple la commande va parcourir chaque ligne de fichier.
Vu qu'on cherche le nombre d'occurrence du 1er mot de chaque ligne alors il suffit de considérer le 1er mot comme clé et vu qu'elle devrait être unique alors il me suffira par la suite de compter la valeur.

Voici ce qui se passe sur le capot.

Traitement de la 1ère ligne
la clé est simon et la valeur sera 1

Traitement de la 2ème ligne
la clé est simon et la valeur sera 2 (la valeur est incrementé à chaque passage)

Tout ça pour tout les simon quelque soit le numéro de la ligne dans le fichier (donc les ligens ayant simon au début n'ont pas besoin d'être groupée)

Quand on arrive à fabien alors c'est une nouvelle clé et à l'instar de la clé simon la valeur sera incrémenté et ainsi de suite jusqu'à la dernière ligne de fichier.

A la fin le hash a un peu cette forme (à savoir qu'on peut trier le hash mais pas besoin dans ce cas) qui est interne donc aléatoire et pas dans l'ordre de création de hash
%h = (
      "seb"    => 1,
      "yoann"  => 6,
      "simon"  => 4,
      "fabien" => 2,
);


A ce moment le hash est dans la mémoire vive et il faudrait le sauvegarder quelque part, j'ai choisi un fichier.
Le bloc END{} permet qu'une fois arrivé à la fin de fichier, d'afficher le hash.
Pour enregistrer dans le fichier j'ai utiliser une simple redirection de STDOUT (sortie standard, l'écran) vers un fichier.


Voilà le fonctionnement pour la 1ère commande.
Les option utiliser permet de spliter les mots de chaque ligne dans un tableau @F et ensuite j'utilise $F[0] - le 1er élément (simon, seb, fabien, yoann)

La 2ème commande

perl -ne '$h{$1}=$2 if /(.*):(.*)/;s/^(.*?)\s(.*?)\sx(.*)/$1 $2 $h{$1} $3/ and print' visiteurr.occ visiteurr

Cette commande lit les deux fichiers :
- celui créé par le 1ère commande qui contient le nombre d'occurences
- le fichier original.

La commande contient deux lignes de code séparées par point-virgule
$h{$1}=$2 if /(.*):(.*)/
et
s/^(.*?)\s(.*?)\sx(.*)/$1 $2 $h{$1} $3/ and print

La commande $h{$1}=$2 if /(.*):(.*)/ au moment de la lecture du 1er fichier va recréer le hash.
Cette fois si le séparateur n'est plus l'espace mais les deux points
(.*):(.*) c'est une expression régulière qu'on pourrait la traduire comme ça

. veut dire n'importe quel caractère
*</gas> c'est un quantificateur qui permet de trouver 0,1 ou n'importe combien de caractères
<gras>()
les parenthèses c'est pour capturer le motif trouvé
: c'est le caractère littéral

Les captures sont numéroté de 1 à .... et les variables correspondante sont $1, $2 .....

Ce qui est intéressant c'est que le hash sera rempli si est seulement la ligne contient un : (ça pourrait poser des problèmes de mémoires pas de résultat si le fichier original contiendra :)
On pourrait améliorer en utilisant les ancrages de début et fin chaîne. (^ - début ; $ - fin)

Tu pourrais te demander pourquoi on ne l'as pas fait d'un coup au lieu de créer un fichier temporaire.
Si le fichier est de grande taille (disons des millions des lignes) alors je te laisse imaginé de combien de mémoire vive + swap on devrait avoir pour stoker tout ça.
Bon le cas le plus défavorable sera si le fichier original contiendrait une clé par ligne, mais en ce cas il n'y aura plus besoin de compter le nombre d'occurrences et en ce cas l'ajout du 1 dans le colonne serait suffisant

Donc $h{$1}=$2 if /(.*):(.*)/ dit en bref : remplie moi le hash avec cle => valeur si est seulement la ligne lu dans le fichier contient :

A la fin de la lecture du 1er fichier, le hash est rempli et c'est la lecture du fichier original qui commence.

s/^(.*?)\s(.*?)\sx(.*)/$1 $2 $h{$1} $3/ and print

Sachant que le séparateur est l'espace alors il suffit de séparer les mots et ensuite remplacer le x avec la valeur correspondant qui se trouve dans le hash

s/MOTIF/REMPLACEMENT/ c'est la fonction substitute qui permet de remplacer la partie gauche avec ce qui se trouve à droite

La partie MOTIF
s/^(.*?)\s(.*?)\sx(.*)/

s/
^ -ancrage début chaine
( - début 1ère capture - $1
.*? - n'importe quel caractère 0,1 ou n'importe combien des fois mais éviter la gourmandise
) - fin 1ère capture
\s - cherche un espace
( - début 2ème capture - $2
.*? - n'importe quel caractère 0,1 ou n'importe combien des fois mais éviter la gourmandise
) - fin 2ème capture
\sx - c'est ici le champ concerné pour le changement
( - la 3ème capture - $3
.* - n'importe quel caractère 0,1 ou n'importe combien des fois, gourmande cette fois
) - fin de la 3ème capture

Attention, si la colonne a modifié ne contient pas x alors il faudrai changer la regex

La partie REMPLACEMENT

/$1 $2 $h{$1} $3/ and print

/
$1 - la 1ère capture
$2 - espace la 2ème capture
$h{$1} - espace et voir (nombre occurrence)
$3 - espace et la 3ème capture
/ and print - fin de remplacement et affiche

nombre occurence $h{$1}
La 1ère capture c'est le 1ère mot de la ligne.
$h{$1} par exemple quand le mot est simon on a :

$h{"simon"} et dans le hash on a vu que la valeur de simon est le nombre d'occurrences trouvées par le 1ère commande, donc 4

Cette substitution est appliquée pour chaque ligne.

Voilà, j'espère que c'est un peu plus clair.


c'est lui le spécialiste en Perl ;-))
Pas menteur en ce qui concerne la connexion, mais pour le reste oui ;-))
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
Modifié par lami20j le 9/02/2011 à 18:01
Salut,

A vrai dire mon test est fait sur un exemple qui semble n'est pas être conforme à ton fichier.
Pour ça j'aurais peut être besoin de ton fichier.
Tu peux me l'envoyer par mail.

petite précision aussi ... diference entre ".*?" et juste ".*" ?

Voici un exemple pour voir la différence.
Tu remarques quand j'utilise .* alors $1 vaut xigenc - .* a avalé tout jusqu'au dernière e, donc la plus longue chaine
En revanche quand j'utilise .*? alors $1 vaut xig - .*? a avalé jusqu'au 1er e, donc la chaine minimale

:~$ echo exigence    
exigence   
:~$ echo exigence | perl -ne '/e(.*)e/ ; print "$1\n"'   
xigenc   
r:~$ echo exigence | perl -ne '/e(.*?)e/ ; print "$1\n"'   
xig
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 415
7 févr. 2011 à 19:12
Salut,

Pour ça j'aurais peut être besoin de ton fichier.
Tu peux me l'envoyer par mail.

Déjà demandé, mais ce n'est pas possible, par contre les lignes originelles ressemblent à ça ;-\
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
7 févr. 2011 à 19:20
Salut,

Déjà demandé, mais ce n'est pas possible, par contre les lignes originelles ressemblent

Ben, c'est justement ça qui me dérange que ça rassemble, mais personne ne dit ce qui se trouve derrière les caractères non imprimables (espace, tabulation, ou je ne sais pas quoi encore ;-)

Je vais essayer de généraliser.
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 415
7 févr. 2011 à 19:25
Faut faire avec.... mais c'est là qu'on voit les véritables bêtes au final ;-))
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
7 févr. 2011 à 20:06
Re,

je comprend pas comment "simuler" des colonnes ...

Vous savez ?


Alors on va essayer de savoir la structure de ton fichier.
Avec cette commande tous les caractères différent des espace, tab sont remplacés par A et les autres par leur code ascii.

perl -ne 'while(/(.)/g){my $x=$1;($x=~/\s/)?(print " ", ord($x), " "):print "A"};print "\n"' visiteurr > visit.struct

Ensuite tu mets le fichier visit.struct sur cjoint.com


Pour preuve voici ce qui affiche chez moi

~$ cat visiteurr
simon ok x febgeg
simon ok x rhedg
simon ok x erze
simon ok x srg e
fabien ok x nrteth
fabien ok x tehhet
seb ok x et ee
yoann ok x eth
yoann ok x et he
yoann ok x ehe
yoann ok x egr
yoann ok x ereh
yoann ok x ete 
~$ perl -ne 'while(/(.)/g){my $x=$1;($x=~/\s/)?(print " ", ord($x), " "):print "A"};print "\n"' visiteurr > visit.struct
lami20j@debian-acer:~$ cat visit.struct 
AAAAA 32 AA 32 A 32 AAAAAA
AAAAA 32 AA 32 A 32 AAAAA
AAAAA 32 AA 32 A 32 AAAA
AAAAA 32 AA 32 A 32 AAA 32 A
AAAAAA 32 AA 32 A 32 AAAAAA
AAAAAA 32 AA 32 A 32 AAAAAA
AAA 32 AA 32 A 32 AA 32 AA
AAAAA 32 AA 32 A 32 AAA
AAAAA 32 AA 32 A 32 AA 32 AA
AAAAA 32 AA 32 A 32 AAA
AAAAA 32 AA 32 A 32 AAA
AAAAA 32 AA 32 A 32 AAAA
AAAAA 32 AA 32 A 32 AAA 32 

0
RE ^^ alors aprés avoir longement modifié le code pour tenté de l'adapter ^^ voila ce que j'obtient:

perl -ne '$h{$1}=$2 if /(.*):(.*)/;s/^(.*?)\tmodification\t(.*)/$1\t$h{$1}\t$2/ and print' texte.txt.occ texte.tmp.3_2 > texte.txt.tmp.3_3

avec des lignes de ce type :

simon modification 9999.00 test 999.00 tes2 test3 pierre 99.00 test4 yoann 99.00 99.00 grande_phrase 9999999.00 99.00 99.00 9.00 99.00 didier

et ca marche super bien

Malheureusement je n'ai en aucun cas le droit de sortir un document même modifié de mon entreprise ... De plus le fichier possède 16000 lignes trés trés longues ^^ tu me diras c'est pas grand chose lol j'en ai un qui posséde plus de 4 millions de lignes =) ( plus de 200Mo ).
Sur mon exemple si dessu chaque mot est dans une colonne différente et le résultat doit etre :

simon 8 9999.00 test 999.00 tes2 test3 pierre 99.00 test4 yoann 99.00 99.00 grande_phrase 9999999.00 99.00 99.00 9.00 99.00 didier

si Simon aparait 8 fois en première position.

Que pensez vous de mes modifs ? c'est normale que ca marche ou c'est un coup de chance et ca va pas marcher tout le temps ?

Merci les gars c'est vraiment sympa
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
8 févr. 2011 à 12:33
Salut,

c'est normale que ca marche ou c'est un coup de chance et ca va pas marcher tout le temps ?

Ce que j'ai besoin ce n'est pas le contenu mais la structure de ton fichier.
Bon, si le fait de dire qu'il y a un mot séparé par un espace ou tabulation est une atteinte à la sécurité alors ils sont parano ;-)


Ce qui m'interesse c'est le séparateur de champ et quelle colonne tu veux remplacer.

et ca marche super bien
Je ne suis pas convaincu.
Ta commande et ta ligne de fichier font deux.
Je vois dans ta regex entre la 1ère et la 2ème capture un deux-point mais pas dans la ligne de ton fichier.
0
re,

Je vois dans ta regex entre la 1ère et la 2ème capture un deux-point mais pas dans la ligne de ton fichier.

je pense que le if /(.*):(.*)/ est par rapport au fichier .occ non ?

effectivement ils sont paranos ^^ c'est le probleme des grosses multinationnales :/

Ce que j'ai besoin ce n'est pas le contenu mais la structure de ton fichier.

le fichier est constitué de lignes toute de meme structure ... 20 colonnes contenant chacune un mot ( ex : test_53_du_01012011 <- ca c'est UN mot ),
la colonne a modifier c'est la 2eme

quant je l'ouvre avec un "more" j'ai l'impression que le séparateur de colonne est une tabulation .

j'espère avoir rrépondu a ta question ... si tu veux d'autres infos hésite pas j'essérai de repondre au mieu...


par contre pour les ":" je n'ai jamais eu de ":" dans mon fichier a traiter.

thx ;)
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
8 févr. 2011 à 16:11
Re,

je pense que le if /(.*):(.*)/ est par rapport au fichier .occ non ?
Tu as raison. Je suis au boulot aussi ;-)
Oublie ce que j'ai dit ;-)

Je vais regarder ce soir.
0
pas de souci ^^ ça veu dire que je commence a comprendre un peu le code lol
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
9 févr. 2011 à 18:00
Salut,

La ligne que tu as modifié est correcte et sur les lignes de type que tu as montré ça marche.

En fait dans mon exemple je faisait le remplacement sur la 3ème colonne et tu veux sur la 2ème.

Normalement \s est une classe de caractères qui inclut la tabulation donc le \t

Tu voulais aussi une explication pour le .*?

Je t'ai donné un exemple ici https://forums.commentcamarche.net/forum/affich-20734055-selection-ligne-suivante-csh-foreach#50

Attention toutefois ce que tu vas utliser comme regex au lieu de modification.
Teste ça

perl -ne '$h{$1}=$2 if /(.*):(.*)/;s/^(.*?)\s.*?\s(.*)/$1\t$h{$1}\t$2/ and print' texte.txt.occ texte.tmp.3_2 > resultat



Pour voir encore ce qui ça fait .* au lieu de .*?
Tu peux tester avec

perl -ne '$h{$1}=$2 if /(.*):(.*)/;s/^(.*?)\s.*\s(.*)/$1\t$h{$1}\t$2/ and print;print "\n"'  texte.txt.occ texte.tmp.3_2 > resultat2
0