#1 Le 07/01/2016, à 18:11
- Tenebrae
Remplacement récurrent
Bonjour,
J'ai un fichier de log dont je dois remplacer la "2eme colonne" dont les lignes ressemble à :
"000024ca600534489abaa2ee0ed09cd1";"Mozilla/5.0 (Linux; Android 5.0; HUAWEI GRA-L09 Build/HUAWEIGRA-L09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile Safari/537.36"
"00026f1e5082b6a2d9f7847f5b8faa0a";"Mozilla/5.0 (Linux; Android Android 5.0.2; 6045Y orange Build/LRX21E) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/38.0.0.0 Mobile Safari/537.36"
"0002dffceb885e4b4a1ce4539132f4f7";"Mozilla/5.0 (iPad; CPU OS 9_2 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13C75 Safari/601.1"
"000365c8121661a28ee750d4626c206d";"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"
"00041b6a344e95fe6a61765f54ccdcb7";"Mozilla/5.0 (Windows NT 5.1; rv:43.0) Gecko/20100101 Firefox/43.0"
Je dois obtenir ceci :
"000024ca600534489abaa2ee0ed09cd1";"Linux"
"00026f1e5082b6a2d9f7847f5b8faa0a";"Linux"
"0002dffceb885e4b4a1ce4539132f4f7";"iPad Mac OS"
"000365c8121661a28ee750d4626c206d";"Windows 10"
"00041b6a344e95fe6a61765f54ccdcb7";"Windows XP"
J'arrive à obtenir le résultat désiré en ulitisant
while read line ;do
local field_1=$( echo "${line}" | awk -F '";"' -v OFS=';' '{print $1}' | sed 's/\"//' );
local field_2=$( echo "${line}" | awk -F '";"' -v OFS=';' '{print $2}' | sed 's/\"//' );
case $field_2 in
*"Windows NT 10"*) sSysteme="Windows 10" ;;
*"Windows NT 6.4"*) sSysteme="Windows 10" ;;
*"Windows NT 6.3"*) sSysteme="Windows 8.1" ;;
*"Windows NT 6.2"*) sSysteme="Windows 8" ;;
*"Windows NT 6.1"*) sSysteme="Windows Seven" ;;
*"Windows NT 6.0"*) sSysteme="Windows Vista" ;;
*"Windows NT 5.2"*) sSysteme="Windows Server 2003" ;;
*"Windows NT 5.1"*) sSysteme="Windows XP" ;;
*"Windows NT 5.0"*) sSysteme="Windows 2000" ;;
*"Windows NT"*) sSysteme="Windows NT" ;;
*"Windows 98"*) sSysteme="Windows 98" ;;
*"iPhone OS"*) sSysteme="iPhone Mac OS" ;;
*"iPad"*) sSysteme="iPad Mac OS" ;;
*"Macintosh"*) sSysteme="Intel Mac OS" ;;
*"Android"*) sSysteme="Adroid" ;;
*"SunOS"*) sSysteme="Sun OS" ;;
*"Fedora"*) sSysteme="Fedora" ;;
*"Haiku"*) sSysteme="Haiku" ;;
*"Ubuntu"*) sSysteme="Linux Ubuntu" ;;
*"Window"*) sSysteme="Windows" ;;
*"iPhone"*) sSysteme="iPhone" ;;
*"Mac"*) sSysteme="Mac OS" ;;
*"Linux"*) sSysteme="Linux" ;;
*) sSysteme="inconnu" ;;
esac
echo "\"${field_1}\";\"${sSysteme}\"" >> "${sTempFile}"
done < "${sOutputFile}"
Comme vous vous en doutez niveau performance c'est assez dégradé.
Y aurait-il un moyen de parvenir au même résultat avec un SED par exemple?
Merci de votre réponse.
Merci d'utiliser les balises code pour insérer les lignes de retours de commandes. Merci.
Dernière modification par Ayral (Le 07/01/2016, à 22:46)
Hors ligne
#2 Le 07/01/2016, à 18:40
- Watael
Re : Remplacement récurrent
salut,
Comme vous vous en doutez niveau performance c'est assez dégradé.
oui, trop de commandes externes !
while IFS=; read -a fields
do
case
...
esac
echo "${fields[0]};\"$sSsyteme\""
done < fichier.log
Dernière modification par Watael (Le 07/01/2016, à 18:57)
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#3 Le 07/01/2016, à 21:49
- tiramiseb
Re : Remplacement récurrent
Attention, il y a des ";" dans les champs.
Il semble fort que ce fichier est au format CSV...
Pourquoi ne pas utiliser des outils qui savent lire nativement du CSV ?
Pour ma part je ferais ça en Python, parce que je connais ce langage... mais il y a d'autres solutions pour lire du CSV...
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#4 Le 07/01/2016, à 22:23
- tiramiseb
Re : Remplacement récurrent
Je réitère ma suggestion : autant utiliser un soft qui sait lire le CSV...
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#5 Le 07/01/2016, à 22:27
- Watael
Re : Remplacement récurrent
Attention, il y a des ";" dans les champs.
ah, oui.
c'est pas grave. il n'y en a pas dans le premier champ, et on ne réutilise que ce premier champ.
le tableau n'est pas indispensable, on peut faire ça sur deux variables :
while IFS=';' read first rest; do :whatever with $first; done <fichier
EDIT: oops, j'ai supprimé un premier jet.
autant utiliser un soft qui sait lire le CSV...
par exemple...
Dernière modification par Watael (Le 07/01/2016, à 22:29)
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#6 Le 07/01/2016, à 22:39
- tiramiseb
Re : Remplacement récurrent
Approche très simpliste, il y a probablement moyen d'améliorer les perfs...
#!/usr/bin/env python
import csv
matches = [
("Windows NT 10", "Windows 10"),
("Windows NT 6.4", "Windows 10"),
("Windows NT 6.3", "Windows 8.1"),
("Windows NT 6.2", "Windows 8"),
("Windows NT 6.1", "Windows Seven"),
("Windows NT 6.0", "Windows Vista"),
("Windows NT 5.2", "Windows Server 2003"),
("Windows NT 5.1", "Windows XP"),
("Windows NT 5.0", "Windows 2000"),
("Windows NT", "Windows NT"),
("Windows 98", "Windows 98"),
("iPhone OS", "iPhone Mac OS"),
("iPad", "iPad Mac OS"),
("Macintosh", "Intel Mac OS"),
("Android", "Adroid"),
("SunOS", "Sun OS"),
("Fedora", "Fedora"),
("Haiku", "Haiku"),
("Ubuntu", "Linux Ubuntu"),
("Window", "Windows"),
("iPhone", "iPhone"),
("Mac", "Mac OS"),
("Linux", "Linux"),
]
with open('file.csv') as csvfile:
lines = csv.reader(csvfile, delimiter=';')
for row in lines:
system="inconnu"
for match in matches:
if match[0] in row[1]:
system = match[1]
break
print '"{}":"{}"'.format(row[0], system)
Dernière modification par tiramiseb (Le 07/01/2016, à 22:42)
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#7 Le 07/01/2016, à 23:52
- Watael
Re : Remplacement récurrent
en bricolant un tout petit peu (parce que le Field Separator crée un premier champ vide), tout en Gawk :
gawk -F'(";")|"' '{switch($3){ case /.*Windows.*/: sSys="W$";break; default: sSys="default";break};print "\""$2"\";\""sSys"\""}' fichierCSV.log
"000024ca600534489abaa2ee0ed09cd1";"default"
"00026f1e5082b6a2d9f7847f5b8faa0a";"default"
"0002dffceb885e4b4a1ce4539132f4f7";"default"
"000365c8121661a28ee750d4626c206d";"W$"
"00041b6a344e95fe6a61765f54ccdcb7";"W$"
Dernière modification par Watael (Le 08/01/2016, à 00:31)
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#8 Le 08/01/2016, à 00:10
- Watael
Re : Remplacement récurrent
hmmf le FS ne fait pas exactement ce que je veux/pense.
je reviens...
edit :
-F '"|(";")'
à confirmer...
edit2:
le FS est mieux (je corrige dans mon post précédent), mais pas moyen, apparemment, de se défaire de ce premier champ inutile. on conserve un décalage dans la numérotation des champs utiles.
edit3:
j'm'em... avec les guillemets, mais puisqu'il doivent apparaître à la sortie, autant ne pas s'en préoccuper :
gawk 'BEGIN{FS=OFS=";"}{switch($2){ case /.*Windows.*/: new="\"W$\"";break; default: new="\"default\"";break;} print $1,new}'
Dernière modification par Watael (Le 08/01/2016, à 16:45)
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#9 Le 08/01/2016, à 07:25
- tiramiseb
Re : Remplacement récurrent
Watael: ou alors on lit le format CSV...
... et là forcément ça marche à la perfection !
Dernière modification par tiramiseb (Le 08/01/2016, à 07:25)
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#10 Le 08/01/2016, à 07:31
- tiramiseb
Re : Remplacement récurrent
(au fait, Tenebrae, sur iPad et iPhone le système est iOS et sur les Mac le système est "OS X" et non "Mac OS")
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#11 Le 08/01/2016, à 09:22
- Compte anonymisé
Re : Remplacement récurrent
sinon avec cut ça peut aussi être pas mal pour lire le csv.
exemple :
local field_1=$( echo "${line}" | awk -F '";"' -v OFS=';' '{print $1}' | sed 's/\"//' );
local field_2=$( echo "${line}" | awk -F '";"' -v OFS=';' '{print $2}' | sed 's/\"//' );
...
echo "\"${field_1}\";\"${sSysteme}\"" >> "${sTempFile}"
deviendrait :
field_1=$(echo "${line}" | cut -f 1 -d ";")
field_2=$(echo "${line}" | cut -f 2,3 -d ";")
...
echo ${field_1}";\"${sSysteme}\"" >> "${sTempFile}"
(je sens que mon post va se faire clasher )
Dernière modification par Compte anonymisé (Le 08/01/2016, à 09:37)
#12 Le 08/01/2016, à 09:26
- tiramiseb
Re : Remplacement récurrent
Anonyme68: non ça ne marchera pas car il y a des ";" dans le second champ : là tu vires tout ce qui se trouve après le deuxième ";"...
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#13 Le 08/01/2016, à 09:32
- Compte anonymisé
Re : Remplacement récurrent
en effet, j'ai remplacé pour que ça fonctionne.
Enfin c'est juste à titre d'information, la solution de Watael en post #7 est pas mal aussi.
#14 Le 08/01/2016, à 09:38
- tiramiseb
Re : Remplacement récurrent
... pourquoi personne ne dit que ma solution propre en #6 est pas mal ? ... :'(
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#15 Le 08/01/2016, à 09:53
- Tenebrae
Re : Remplacement récurrent
Merci pour toute vos réponses.
Je vais testé un peu tout ça.
Hors ligne
#16 Le 08/01/2016, à 09:56
- claudius01
Re : Remplacement récurrent
Bonjour,
Si si tiramiseb, elle très propre ta solution en #6 et qui plus est très évolutive, mais il semble que les intervenants se limitent à du script shell en excluant le Python.
Personnellement dans ce genre de situation et car je considère le format CSV comme propriétaire, je transforme les données à traiter dans un format XML (comme Convert CSV to XML en autre) et après j'ai toute latitude pour choisir le langage + les outils idoines que j'estime appropriés et surtout que je maîtrise en écrivant le minimum de code...
Dernière modification par claudius01 (Le 08/01/2016, à 09:56)
Hors ligne
#17 Le 08/01/2016, à 09:59
- tiramiseb
Re : Remplacement récurrent
il semble que les intervenants se limitent à du script shell
Ce qui est dommage, car ça ne simplifie pas la vie de faire des scripts compliqués comme ça
car je considère le format CSV comme propriétaire
'faut pas abuser non plus, le CSV est quand même plutôt ouvert comme format
Transformer en XML, c'est pas sûr que ce soit le plus facile
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#18 Le 08/01/2016, à 10:04
- claudius01
Re : Remplacement récurrent
...
Faut pas abuser non plus, le CSV est quand même plutôt ouvert comme format
Je te l'accorde, mais ma démarche sera strictement la même avec d'autres formats plus ou moins "propriétaires"...
Hors ligne
#19 Le 08/01/2016, à 10:09
- tiramiseb
Re : Remplacement récurrent
En même temps, vouloir bosser en XML, faut être maso...
JSON ftw !
(mais bon, là on digresse...)
Dernière modification par tiramiseb (Le 08/01/2016, à 10:09)
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#20 Le 08/01/2016, à 10:15
- Tenebrae
Re : Remplacement récurrent
Bonjour,
Si si tiramiseb, elle très propre ta solution en #6 et qui plus est très évolutive, mais il semble que les intervenants se limitent à du script shell en excluant le Python.
Personnellement dans ce genre de situation et car je considère le format CSV comme propriétaire, je transforme les données à traiter dans un format XML (comme Convert CSV to XML en autre) et après j'ai toute latitude pour choisir le langage + les outils idoines que j'estime appropriés et surtout que je maîtrise en écrivant le minimum de code...
Bonjour,
Dans mon cas, pas le choix d'utiliser autre chose que Shell et CSV (format du fichier à traiter et renvoyé)....
De plus, je ne maitrise pas bien Shell et pas du tout Python
Hors ligne
#21 Le 08/01/2016, à 10:24
- tiramiseb
Re : Remplacement récurrent
pas le choix d'utiliser autre chose que Shell
Pourquoi donc ? Python est installé par défaut sur la plupart des distributions, si pas toutes...
Et puis je rappelle que dans ton premier script tu utilises trois choses : un shell, awk et sed. Ce sont trois outils indépendants, dont les versions et les arguments peuvent changer.
Dans mon script, on utilise un seul langage, qui ne va pas changer...
La solution en #7 de Watael, par exemple, ce n'est pas non plus un shellscript.
Il appelle juste gawk (donc il faut que gawk soit installé sur la machine) pour exécuter un script inline. Il aurait très bien pu mettre le contenu de sa chaîne de caractères dans un fichier et mettre gawk dans le shebang de ce fichier (et ça aurait été bien plus propre).
Donc à mon avis, ta contrainte est mal énoncée
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#22 Le 08/01/2016, à 11:09
- claudius01
Re : Remplacement récurrent
Pourquoi donc ? Python est installé par défaut sur la plupart des distributions, si pas toutes...
Et puis je rappelle que dans ton premier script tu utilises trois choses : un shell, awk et sed. Ce sont trois outils indépendants, dont les versions et les arguments peuvent changer.
Dans mon script, on utilise un seul langage, qui ne va pas changer...
+1 pour tiramiseb, car le mélange et l'utilisation de plusieurs outils au gré des besoins est une mauvaise chose.
Dès lors que le format pivot des données (ici le CSV et pour moi le XML voire JSON ;-) est arrêté, se concentrer sur un et un seul langage et leurs outils associés pour éviter le plat de nouilles qui conduit à une programmation itérative, interminable, non évolutive et surtout "inmaintenable"...
Si le bash et le csv sont l'expression du besoin, s'orienter vers un outil ad hoc comme bash csv tool avec en particulier csvkit.
A suivre...
Dernière modification par claudius01 (Le 08/01/2016, à 11:17)
Hors ligne
#23 Le 08/01/2016, à 11:17
- tiramiseb
Re : Remplacement récurrent
claudius01 : as-tu conscience que l'outil que tu proposes, csvkit, est un logiciel supplémentaire à installer, codé en Python, qui s'appuie précisément sur le module standard csv que je propose d'utiliser ?
Dernière modification par tiramiseb (Le 08/01/2016, à 11:19)
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#24 Le 08/01/2016, à 11:20
- tiramiseb
Re : Remplacement récurrent
Plutôt que de dire « utilise bash et installe un logiciel de plusieurs centaines de lignes en python pour parser ton csv et ensuite le traîter en shellscript », je préfère dire « fais un script de 20 lignes exclusivement en python, sans nécessiter quoi que ce soit d'autre »
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#25 Le 08/01/2016, à 11:20
- claudius01
Re : Remplacement récurrent
J'en suis conscient @ "as-tu conscience que l'outil que tu proposes, csvkit, ..." mais je tiens compte de: "De plus, je ne maitrise pas bien Shell et pas du tout Python" écrit par notre ami Tenebrae à qui on pourrait répondre et conseiller: C'est l'occasion de s'y mettre [à Python] mais cela ne dépend pas de nous...
Dernière modification par claudius01 (Le 08/01/2016, à 11:24)
Hors ligne