Help pour SED - Shell/Batch - Programmation
Marsh Posté le 08-02-2007 à 11:42:03
Fred_l a écrit : Bonjour, j'ai un problème avec sed. |
Bon, les remarques de bases: cat ... |while read Line c'est bien pensé. Le seul soucis, c'est que si tu modifies une variable dans le pipe, elle est perdue en fin de done. Bon là t'es pas concerné mais faudra y penser si un jour ça t'arrive. On peut faire différemment de cette façon
exec 3<fichier |
Pas de pipe donc pas de perte de variable.
Ensuite, tester si "Resu" (le résultat du "grep" ) = 0 c'est pas bon. Le grep te renvoie une ligne ou pas, donc tu testes si "Resu" est vide ou pas => "test -n" ou "test -z"
Ou alors tu testes si le grep réussi ou pas => if cat Format2 |grep $Domain 1>/dev/null ou plus simplement "if grep $Domain Format2 1>/dev/null"
Maintenant, j'ai pas examiné en détail ton algo (probablement parce qu'il y avait trop de commentaires), mais ta condition pour dire "on est sur la même ligne" c'est dire "est-ce que je trouve $Domain dans Format2" je trouve ça lourd => tu examines tout un fichier avec "grep" alors que seule la dernière ligne t'intéresse => tu aurais pu faire mieux avec "tail". Mais de toute façon je trouve ton truc trop fouillis. Pourquoi, quand tu es sur la ligne contenant "ASPAWAY", ne pas mémoriser ce fait et tant que t'es sur la même ligne, tu concatènes les autres champs puis, dès que t'as changé de ligne, tu écris la précédente ligne concaténée ?
Je verrais bien un truc de ce style
#!/bin/sh |
Marsh Posté le 08-02-2007 à 20:26:25
Tu peux essayer en Perl :
|
C'est sans doute pas optimal, mais ça a l'avantage de ne parcourir le fichier d'entrée qu'une seule fois. Les descriptions sont données dans l'ordre alphabétiques, les domaines aussi, et les serveurs dans un ordre arbitraire.
$ ./monprog.pl fichier_entree.txt > fichier_sortie.txt |
Marsh Posté le 08-02-2007 à 21:21:10
Sinon avec awk (si tu as sed, tu doit avoir awk). Encore une fois, le fichier n'est parcouru qu'une seule fois et un seul processus est lancé, mais ça suppose que les descriptions et les serveurs soient dans l'ordre dans le fichier d'entrée.
Par exemple, cette entrée fonctionnera :
|
Mais celle-ci ne fonctionnera pas :
|
Voici le script awk :
|
Il commence par écrire un retour à la ligne, ce qui est un mini-défaut. Tu peux l'adapter.
$ ./script.awk entree.txt > sortie.txt |
Marsh Posté le 08-02-2007 à 21:24:05
frednoob a écrit : |
Mon script aussi ne lit le fichier d'entrée qu'une seule fois...
Marsh Posté le 08-02-2007 à 21:31:54
Sve@r a écrit : Mon script aussi ne lit le fichier d'entrée qu'une seule fois... |
Mais le fichier de sortie est lu plusieurs fois. De plus, si l'écriture est bufferisée, peut-être que ça peut poser problème, sauf à s'assurer de vider le buffer après chaque ajout. Je ne suis pas sûr cela dit. Je préfère aussi utiliser un seul processus plutôt que d'en lancer plusieurs (cat, grep, etc.). D'ailleurs, tu peux améliorer
cat $Format2 | grep $Domain |
en
grep $Domain $Format2 |
Ça fait toujours un processus de moins.
Pendant que j'y suis, voici une petite amélioration de mon script awk (utilise moins de mémoire) :
|
Marsh Posté le 09-02-2007 à 07:26:11
frednoob a écrit : Mais le fichier de sortie est lu plusieurs fois. De plus, si l'écriture est bufferisée, peut-être que ça peut poser problème, sauf à s'assurer de vider le buffer après chaque ajout. Je ne suis pas sûr cela dit. Je préfère aussi utiliser un seul processus plutôt que d'en lancer plusieurs (cat, grep, etc.). |
Tes remarques s'appliquent au script de Fred_L (premier post) et non au mien (deuxième post) - Va relire les posts du début !!!
Mon script ne lit qu'une seule fois un seul fichier qui est le fichier d'entrée
frednoob a écrit : D'ailleurs, tu peux améliorer
|
Ca aussi je l'ai dit dans mon premier post !!!
Marsh Posté le 09-02-2007 à 12:40:43
Ah oui, désolé Sve@r. Par contre, ton script ne fonctionne que pour les lignes ASPAWAY, et on ne sait pas si ce cas particulier suffit à résoudre le problème, ou si d'autres lignes peuvent avoir besoin d'être regroupées (ce que j'ai supposé dans mes exemples).
Marsh Posté le 09-02-2007 à 15:58:38
frednoob a écrit : Ah oui, désolé Sve@r. Par contre, ton script ne fonctionne que pour les lignes ASPAWAY, et on ne sait pas si ce cas particulier suffit à résoudre le problème, ou si d'autres lignes peuvent avoir besoin d'être regroupées (ce que j'ai supposé dans mes exemples). |
Exact - Il avait parlé de "ASPAWAY" donc je n'ai considéré que ASPAWAY...
Si la contrainte devient "reconnaitre plusieurs mots", on reverra le script...
Marsh Posté le 08-02-2007 à 08:54:19
Bonjour, j'ai un problème avec sed.
voilà ce que je veux faire:
fichier1 contient:
| AGF | MJ0 | MOPB4TSMSV-01 |
| AGF | MJ0 | MOPB4TSMSV-01 |
| AGS | FA3 | MOPB4TSMSV-05 |
| AIR_LIQUIDE | L02 | MOPB2TSMSV-01 |
| ALC_EVILOG | TY3 | MOPB2TSMSV-03 |
| ALC_INFOR | A39 | MOPB2TSMSV-03 |
| ALC_IPNERGIE | GE1 | MOPB2TSMSV-03 |
| AMS | YM0 | MOPB2TSMSV-05 |
| AMS | YM0 | MOPB2TSMSV-05 |
| ARKEMA | RK0 | MOPB4TSMSV-05 |
| ASPAWAY | IX3 | MOPB2TSMSV-05 |
| ASPAWAY | IX3 | MOPB4TSMSV-05 |
| ASPAWAY | IX3 | MOPB2TSMSV-05 |
| ASPAWAY | IX3 | MOPB4TSMSV-05 |
| ASPAWAY | IX3 | MOPB2TSMSV-05 |
| ASPAWAY | IX3 | MOPB4TSMSV-05 |
| ASPAWAY | IX3 | MOPB2TSMSV-05 |
| ASPAWAY | IX3 | MOPB2TSMSV-05 |
| ASPAWAY | IX3 | MOPB4TSMSV-05 |
| ASPAWAY | IX3 | MOPB2TSMSV-05 |
| ASPAWAY | IX3 | MOPB2TSMSV-05 |
| ASPAWAY | IX3 | MOPB4TSMSV-05 |
| ASPAWAY | IX3 | MOPB2TSMSV-03 |
| ASPAWAY_GEHIS | IX3 | MOPB2TSMSV-05 |
ce que je veux en sortie c'est: ( Ligne ASPAWAY avec les trois serveurs )
| AGF | MJ0 | MOPB4TSMSV-01 |
| AGS | FA3 | MOPB4TSMSV-05 |
| AIR_LIQUIDE | L02 | MOPB2TSMSV-01 |
| ALC_EVILOG | TY3 | MOPB2TSMSV-03 |
| ALC_INFOR | A39 | MOPB2TSMSV-03 |
| ALC_IPNERGIE | GE1 | MOPB2TSMSV-03 |
| AMS | YM0 | MOPB2TSMSV-05 |
| ARKEMA | RK0 | MOPB4TSMSV-05 |
| ASPAWAY | IX3 | MOPB2TSMSV-05 | MOPB4TSMSV-05 | MOPB2TSMSV-03 |
| ASPAWAY_GEHIS | IX3 | MOPB2TSMSV-05 |
voici mon code :
######################
# Domain_Name is not only one per line
# Format to Description | Domain_Name | TSM_Server1 | TSM_Server2 ...
######################
rm -f $Format2 2>&-
rm -f $Format3 2>&-
#############
# on lit le fichier de départ ligne par ligne
#############
cat $TrigramClient | while read Line
do
Descri=`echo $Line | cut -d"|" -f2`
Domain=`echo $Line | cut -d"|" -f3`
Server=`echo $Line | cut -d"|" -f4`
#############
# on cherche dans le fichier 2 s'il y a une occurence
#############
Resu=`cat $Format2 | grep $Domain`
if [ ${#Resu} = 0 ]
then
#############
# si pas d'occurence on écrit la ligne dans le fichier2
#############
print "$Line" >> $Format2
else
#############
# sinon on récupère le nom du serveur TSM dans le fichier2
# pour le comparer avec le nom du serveur dans le fichier1
# Si c'est le même on écrit rien dans le fichier2
#############
Resu2=`cat $Format2 | grep $Domain | cut -d"|" -f4`
if [ $Resu2 != $Server ]
then
#############
# La je veux Soit ajouter le nouveau serveur en fin de ligne du fichier2
# Soit supprimer la ligne du fichier2 et la remplacer avec ligne du fichier1
# + le nom du serveur déjà répertorié dans le fichier2
#############
sed "s/$Ligne/$Ligne $Resu2 |/g $Format2
sleep 15
fi
fi
done
Mais a que j'y arrive pas ! Alors merci pour votre aide ou solution différente...