Swisslinux.org

− Le carrefour GNU/Linux en Suisse −

 

Langue

 

Le Forum

Vous n'êtes pas identifié.

#1 16 May 2008 10:24:24

yanimal
Citoyen(ne)
 
Date d'inscription: 16 May 2008
Messages: 12

probleme de mise en forme de la date en bash

Bonjour a tous, je suis venu ici en esperant un petit coup de main smile
je vous explique tout de suite le probleme : je recupere un fichier d'accounting d'imprimante et je fait divers traitement dessus
seulement je me retrouve bloqué :

j arrive a une ligne de cette forme :

manuel|...........|1|4/17/2008 15:05:02|0.000000|0.000000|0.000000|0.095604|0.000000|0.005946|...........|SGINFO|A4_B|coste

mon probleme est que je dois mettre la date sous cette forme : 2008-4-17 15:05:02 tout en conservant les autres champs afin de l inserer dans un bon format pour ma bd

j'ai teste diverses méthodes et celle qui s'en est le plus rapproche est celle ou je remplace l'espace au centre de la date par un espace suivi d'un delimiteur afin d inverser les champs a ma guise

seul probleme, le nom d'utilisateur, premier champ, peut lui aussi possédé un espace   ex : "Vincent Motto-Ros"
je ne vois plus comment m'en dépatouiller et cela me bloque pour la suite du traitement ( je peux charger la date en tant que chaine de caractere pour faciliter mais le probleme c est que par la suite je vais avoir besoin de selectionner des lignes en fonction de la date, donc pas possible)

si quelqu'un pouvait m'aider ce serait super

Hors ligne

 

#2 16 May 2008 13:30:34

[GO]Skywalker13
Modérateur
Lieu: Choëx (VS)
Date d'inscription: 05 Oct 2004
Messages: 896
Site web

Re: probleme de mise en forme de la date en bash

Salut, fais le avec les expressions régulières (rationnelles)

un truc du style:

Code:

TEST="manuel|...........|1|4/17/2008 15:05:02|0.000000|0.000000|0.000000|0.095604|0.000000|0.005946|...........|SGINFO|A4_B"

echo $TEST | sed "s%\(.*\)|\([[:digit:]]*\)/\([[:digit:]]*\)/\([[:digit:]]*\) \(.*\)%\\1|\\4-\\2-\\3 \\5%"

Et la petite vérif du sed au-dessus:

Code:

$ echo $TEST
manuel|...........|1|4/17/2008 15:05:02|0.000000|0.000000|0.000000|0.095604|0.000000|0.005946|...........|SGINFO|A4_B
$ echo $TEST | sed "s%\(.*\)|\([[:digit:]]*\)/\([[:digit:]]*\)/\([[:digit:]]*\) \(.*\)%\\1|\\4-\\2-\\3 \\5%"
manuel|...........|1|2008-4-17 15:05:02|0.000000|0.000000|0.000000|0.095604|0.000000|0.005946|...........|SGINFO|A4_B

J'ai pondu l'expression rapidement.. faudrait bien vérifier et(ou) améliorer.


Mathieu SCHROETER
log.schroetersa.ch

Hors ligne

 

#3 16 May 2008 13:51:10

yanimal
Citoyen(ne)
 
Date d'inscription: 16 May 2008
Messages: 12

Re: probleme de mise en forme de la date en bash

je te remercie   je te tiendrais au courant lundi sur l'évolution du problème smile

Hors ligne

 

#4 19 May 2008 16:51:48

yanimal
Citoyen(ne)
 
Date d'inscription: 16 May 2008
Messages: 12

Re: probleme de mise en forme de la date en bash

juste un tit mot pour te dire que ca marchait à la perfection ; toutefois serait il possible que tu m'expliques en détail la commande :
en effet je risque d'avoir a faire plusieurs commandes rationnelles et je manque cruellement d'experience avec sed : ne comprenant pas toutes les subtilités je serais totalement incapable d'exploiter une telle ligne
merci bien smile

Hors ligne

 

#5 19 May 2008 20:13:04

[GO]Skywalker13
Modérateur
Lieu: Choëx (VS)
Date d'inscription: 05 Oct 2004
Messages: 896
Site web

Re: probleme de mise en forme de la date en bash

Pour t'expliquer au complet les expressions rationnelle il me faudrait écrire un livre..

alors je vais me contenter de t'expliquer juste l'expression que je t'ai proposé. Si tu veux en savoir plus je te conseil de chercher de la doc directement via ton moteur de recherche favoris.

Bref

Code:

sed "s%\(.*\)|\([[:digit:]]*\)/\([[:digit:]]*\)/\([[:digit:]]*\) \(.*\)%\\1|\\4-\\2-\\3 \\5%"

man sed
c'est bien aussi.. mais bref ;-)

dans l'exemple il y a cette forme:
sed "s%%%"
qui aurait pu être
sed "s///" ou sed "s###"
peu importe car % ou / ou # sont juste là comme délimiteur entre ce qu'il doit chercher et avec quoi il le change.
en résumé c'est sed "s/qui/par quoi/"
le 's' il dit qu'on va faire un remplacement
donc si tu fais
echo "lol lol" | sed "s/lol/mdr/"
ca va remplacer le premier lol par mdr sur la ligne donc : "mdr lol"
si tu fais
echo "lol lol" | sed "s/lol/mdr/g"
ca va remplacer tous les lol par mdr tjrs sur la ligne donc : "mdr mdr"

si tu fais
cat mon_fichier | sed "s/lol/mdr/"
ca va remplacer le premier lol trouvé sur chaque ligne. et avec g sur toute la ligne..
bref on pourrait faire
sed "s/foo/bar/" monfichier
c'est plus propre et meme rajouter -i pour éditer sur place et pas rediriger dans le stdout..
mais bon je te laisse lire le man..

ensuite un truc sympa c'est les expressions rationelles.. alors je vais directement t'expliquer tout l'exemple en une fois pour pas passer des heures..

donc

Code:

sed "s%\(.*\)|\([[:digit:]]*\)/\([[:digit:]]*\)/\([[:digit:]]*\) \(.*\)%\\1|\\4-\\2-\\3 \\5%"

découpons le problème
\(.*\)
|
([[:digit:]]*\)
/
\([[:digit:]]*\)
/
\([[:digit:]]*\)
  (y a un espace ici)
\(.*\)

les \ sont juste la pour protéger les (), en fait ici les parenthèse sont utiles pour dire ce que l'on veut récupérer dans la partie de droite du "s//la partie ici/"
le point veut dire n'importe quel caractère.. donc .* veut dire n'importe quel caractère qu'il soit présent 0 fois ou plusieurs fois.. y a plein de variantes avec +, ? .. bref
[[:digit:]] veut dire qu'on veut un chiffre, à la place on aurait pu écrire [0-9] qui veut dire les chiffres de 0 à 9.. on aurait même pu écrire [0123456789]
donc [[:digit:]]* signifie 0 fois ou plusieurs chiffres

Je te laisse réfléchir un peu maintenant.. encore juste une info concernant les parenthèses..

dans la partie de droite du sed tu vois %\\1|\\4-\\2-\\3 \\5%
en fait le \\1 fait appelle au premier groupe de parenthèse, le \\2 au deuxième etc..
donc \1 c'est le .* (ce qu'il y a avant la date)
le \4 c'est l'année
\2 le mois, etc..  ici tu vois bien que j'ai déplacé l'année en première position, le mois en deuxième.. et que j'ai changé les / en -


c'est extrêmement puissant comme système.. tu peux absolument tout faire avec juste les commandes sed, grep et cat.


Mathieu SCHROETER
log.schroetersa.ch

Hors ligne

 

#6 20 May 2008 10:47:02

yanimal
Citoyen(ne)
 
Date d'inscription: 16 May 2008
Messages: 12

Re: probleme de mise en forme de la date en bash

bah tu ferais un très bon prof   smile   
d'apres ce que je comprend tu cherches l'expression de forme     delimiteur suivi par nombre suivi par nombre suivi par nombre ( avec les / entre)
le .* selectionne donc tout ce qui précède puis à la fin tout ce qui suit
et après tu réécris dans l'ordre
j'avais remarque que sed était puissant mais je me doutais pas qu'on puisse faire quelque chose d'apriori si compliqué par quelque chose d'aussi simple

mais toutefois je risque de faire a nouveau appel à tes services pour un problème du même genre mais qui reste compliqué :

lorsque je récupère le fichier  la ligne initiale est de cette forme :

8, AppSocket, Gérard, machine.ujf-grenoble.fr, The_Edinburgh_Journal_of_Science.pdf, The_Edinburgh_Journal_of_Science.pdf, 8, 16, 4/18/2008 10:46:57, 4/18/2008 10:49:26, 00:02:29, Plain Paper, A4, 0.2845%, 0.2140%, 0.1804%, 1.3485%, 0.0519%

le délimiteur de base attribuée par l'imprimante est donc la virgule et j'ai donc 18 champs fixe

problème : le 5eme et 6 eme champ, a savoir le nom du fichier imprimé s'avère problématique : j'ai remarqué que certains fichiers imprimés pouvait contenir une virgule ( smile quelle chance ) je me retrouve donc parfois avec 22 champs ( ou plus ca depend du nombre de virgules )
cela n'empeche pas mon script de tourner mais ces lignes deviennent inexploitables

mon idée serait de supprimer directement ces champs

au debut je pensais réécrire la ligne jusqu'a "machine.ujf" compris , faire un reverse de la ligne puis reecrire jusqu'au dernier chiffre mais je ne sais pas comment faire si jamais le fichier est nommée par un chiffre

Dernière modification par yanimal (20 May 2008 10:48:22)

Hors ligne

 

#7 20 May 2008 16:52:09

[GO]Skywalker13
Modérateur
Lieu: Choëx (VS)
Date d'inscription: 05 Oct 2004
Messages: 896
Site web

Re: probleme de mise en forme de la date en bash

facile

une manière de faire (j'ai rajouté exprès plein de virgules dans les noms des fichiers pour prouver que ca marche):

Code:

$ TEST="8, AppSocket, Gérard, machine.ujf-grenoble.fr, The_Edin,burgh_Jo,urnal_of_Sc,ience.pdf, The_Edinburgh_,,,Journal_of_Science.pdf, 8, 16, 4/18/2008 10:46:57, 4/18/2008 10:49:26, 00:02:29, Plain Paper, A4, 0.2845%, 0.2140%, 0.1804%, 1.3485%, 0.0519%"

$ echo $TEST
8, AppSocket, Gérard, machine.ujf-grenoble.fr, The_Edin,burgh_Jo,urnal_of_Sc,ience.pdf, The_Edinburgh_,,,Journal_of_Science.pdf, 8, 16, 4/18/2008 10:46:57, 4/18/2008 10:49:26, 00:02:29, Plain Paper, A4, 0.2845%, 0.2140%, 0.1804%, 1.3485%, 0.0519%

$ echo $TEST | sed "s#\([^,]*,[^,]*,[^,]*,[^,]*\),.*,.*,\([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*\)#\1, file, file,\2#"
8, AppSocket, Gérard, machine.ujf-grenoble.fr, file, file, 8, 16, 4/18/2008 10:46:57, 4/18/2008 10:49:26, 00:02:29, Plain Paper, A4, 0.2845%, 0.2140%, 0.1804%, 1.3485%, 0.0519%

bien sûr que ,.*,.*, c'est supide, on peut directement écrire .* à la place
mais sinon c'est moins pédagogique
et [^,]* ca veut dire que les caractères peuvent être tout sauf une virgule.. le ^ faisant office de "différent de" dans ce cas précis.. attention car il peut aussi vouloir dire que c'est le début de la ligne.. ca dépend de comment il est utilisé.


Mathieu SCHROETER
log.schroetersa.ch

Hors ligne

 

#8 21 May 2008 17:46:46

yanimal
Citoyen(ne)
 
Date d'inscription: 16 May 2008
Messages: 12

Re: probleme de mise en forme de la date en bash

ta commande marche pas mal mais il me reste un problème sad
dans le cas ou ces fameux noms de fichiers possèdent également d'autres caractères ca a l'air de poser problèmes
genre ":"  "\" etc....  ca me parait bizarre
egalement en présence de majuscules ? smile
lorsque j utilise ta commande voici le genre de noms de fichiers qui restent :
C:Documents and SettingsGra...9cp.defaultCacheB267EF66d01
CJO - Abstract - Effets de réseau dans la science pré-institu...
http://catalogue.bm-grenoble.fr:81/cgi- … 4&s...
La_science_des_pierres_pr__cieuses__appl.pdf
etc ...
serait il possible de readapter pour sauter tout ces caractères ?

Dernière modification par yanimal (21 May 2008 17:51:01)

Hors ligne

 

#9 21 May 2008 20:54:39

[GO]Skywalker13
Modérateur
Lieu: Choëx (VS)
Date d'inscription: 05 Oct 2004
Messages: 896
Site web

Re: probleme de mise en forme de la date en bash

donne des exemples de lignes qui soient concrètent..

après le seul problème c'est s'il y a des virgules dans les noms des fichiers.. car il devient impossible de savoir quel virgule fait office de séparateur et lesquels sont dans le nom (c'est pour cela que j'ai forcé "file" à la sortie). Les autres caractères n'ont aucune raisons de poser problème.


Mathieu SCHROETER
log.schroetersa.ch

Hors ligne

 

#10 22 May 2008 14:17:25

yanimal
Citoyen(ne)
 
Date d'inscription: 16 May 2008
Messages: 12

Re: probleme de mise en forme de la date en bash

oula c'est moi qui ai du faire le cancre  ^^  en traitement local ca fonctione, c'est juste quand je l'incorpore au script que ca deconne ..... j'etudie le probleme et je te tiens au courant

Hors ligne

 

#11 22 May 2008 16:59:19

yanimal
Citoyen(ne)
 
Date d'inscription: 16 May 2008
Messages: 12

Re: probleme de mise en forme de la date en bash

gros problème type mystère sans réponse ..............
j ai adapté ta requête sous forme de script
voici a quoi il ressemble :

#! /bin/bash

#on efface la precedente trace d'utilisation
rm ./final.txt


while read line
do

var=$(echo "$line")
#echo $var

# expression rationnelle
var2=$(echo $var | sed "s#\([^,]*,[^,]*,[^,]*,[^,]*\),.*,.*,\([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*\)#\1, file, file,\2#")
#echo $var2
echo "$var2" >> ./final.txt



done < $1



ce script fonctionne parfaitement depuis le bureau quand je l applique sur mon fichier à traiter

problème : j ai donc creer ce script dans mon dossier de traitement et j y fais appel durant les différentes procédures de mon script principal
je l applique toujours sur le fameux fichier à traiter mais la , magie, toutes les lignes ne sont pas traitées : je precise que c est exactement le même algo et exactement le meme fichier source
je me suis donc dis que durant le traitement , le fichier source à traiter etait peut etre encore en cours de traitement
j ai donc bien separer chacune des mes actions par un ";" et separer de plusieurs sleep de 10 sec histoire d'etre sur : mais toujours rien
le script ne veut pas s appliquer sur toutes les lignes

Hors ligne

 

#12 22 May 2008 17:47:20

BOFH
Admin
Lieu: Ecublens, VD
Date d'inscription: 03 Feb 2005
Messages: 862
Site web

Re: probleme de mise en forme de la date en bash

Oh my god.

sed, par défaut, applique la commande à chaque ligne. Tout cet enrobage est probablement inutile.

Code:

#!/bin/bash
sed -e "s#\([^,]*,[^,]*,[^,]*,[^,]*\),.*,.*,\([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*\)#\1, file, file,\2#" "$1" >final.txt

ferait aussi l'affaire. Pour le reste, si tes lignes contiennent des paths à la Windows, il est probable que certains \ soient échappés par les multiples passages dans la commande echo. Il est aussi possible que certains espaces ou méta-caractères soient gobés par le shell, toujours pour la même raison.

En revanche, le "final.txt" est très certainement superflu et introduit un risque supplémentaire, tu peux probablement ajuster ton script principal pour lire dans un pipe à la place.

Hors ligne

 

#13 22 May 2008 18:47:34

[GO]Skywalker13
Modérateur
Lieu: Choëx (VS)
Date d'inscription: 05 Oct 2004
Messages: 896
Site web

Re: probleme de mise en forme de la date en bash

BOFH a écrit:

Oh my god.

sed, par défaut, applique la commande à chaque ligne. Tout cet enrobage est probablement inutile.
.

s/probablement/totalement

surtout que dans le deuxième message que j'ai écris dans ce topic j'ai explicitement parlé de ça:

si tu fais
cat mon_fichier | sed "s/lol/mdr/"
ca va remplacer le premier lol trouvé sur chaque ligne. et avec g sur toute la ligne..
bref on pourrait faire
sed "s/foo/bar/" monfichier
c'est plus propre et meme rajouter -i pour éditer sur place et pas rediriger dans le stdout..
mais bon je te laisse lire le man..

Faut mieux me lire yanimal ;-)


Mathieu SCHROETER
log.schroetersa.ch

Hors ligne

 

#14 23 May 2008 10:01:19

yanimal
Citoyen(ne)
 
Date d'inscription: 16 May 2008
Messages: 12

Re: probleme de mise en forme de la date en bash

oula je suis vraiment confus sad   je sais pas ce qui m'est passe par la tête car jusqu a maintenant en plus j'utilisais bien le sed de cette facon .... mdr

Hors ligne

 

#15 23 May 2008 10:25:44

yanimal
Citoyen(ne)
 
Date d'inscription: 16 May 2008
Messages: 12

Re: probleme de mise en forme de la date en bash

rectification  il manque probablement quelque chose dans l'algorythme car ca me fait la même chose sur le bureau lol 
c est ce genre de noms qui deconne :
, Sélectionnez votre aller, Sélectionnez votre aller,
, The_Edinburgh_Journal_of_Science.pdf, The_Edinburgh_Journal_of_Science.pdf,
, Histoire birefringence.doc, Histoire birefringence.doc,
, Modalitéspratiques[1].pdf, Modalitéspratiques[1].pdf,
, CV_COUZON.pdf, CV_COUZON.pdf,
, XLAB.EDEMA_02, XLAB.EDEMA_02,
etc...........

Hors ligne

 

#16 23 May 2008 11:26:36

yanimal
Citoyen(ne)
 
Date d'inscription: 16 May 2008
Messages: 12

Re: probleme de mise en forme de la date en bash

ok problème trouvé..... mais je sais pas comment je vais m en depatouiller.....
si j applique l'algo sur mon fichier cible ca ne marche pas .......... si maintenant je fais une copie a la volée à savoir selectionner tout , que je le colle dans un fichier vierge et que j applique l algo sur ce nouveau fichier tout marche.......
il semble y avoir un probleme d'espacement quelques part ou je ne sais quoi..... je suis perdu la ^^

ou alors peut être un problème de mise en mémoire je sais pas trop....

ps : quand j applique sur le fichier cibre originale j'ai une breve apparition d'un fichier sur le bureau nomme "sedXXXXXX" comme un fichier temporaire qui disparait aussitot ce qui n'est pas le cas avec le second fichier

Dernière modification par yanimal (23 May 2008 11:44:52)

Hors ligne

 

#17 23 May 2008 14:30:15

[GO]Skywalker13
Modérateur
Lieu: Choëx (VS)
Date d'inscription: 05 Oct 2004
Messages: 896
Site web

Re: probleme de mise en forme de la date en bash

ce que t'as donné BOFH ca ne va pas?

Et si tu ouvres le fichier original avec VI, y a des trucs louche ou il est parfaitement lisible?


Mathieu SCHROETER
log.schroetersa.ch

Hors ligne

 

#18 23 May 2008 15:06:11

yanimal
Citoyen(ne)
 
Date d'inscription: 16 May 2008
Messages: 12

Re: probleme de mise en forme de la date en bash

j'ai comparer avec un hexa decimal tout semble correcte : les 2 fichiers sont a l'identiques
j ai bien fait comme BOHF disais mais ca n'a rien change au probleme sad
mon sed n est plus en boucle c'est devenu une ligne banale

ah ok VI : bah j ai rien repere de suspect   mafois si tu penses pouvoir avoir plus d infos je suis pret a t envoyer les 2 fichiers et ce fameux script

Dernière modification par yanimal (23 May 2008 15:43:54)

Hors ligne

 

Pied de page des forums

Powered by FluxBB