Précédent   Forum des professionnels en informatique > Systèmes > Linux > Applications > Shell
Shell Vos questions sur l'utilisation des commandes shell
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 24/09/2007, 15h24   #1
Membre du Club
 
Avatar de gege87270
 
Inscription : mai 2007
Messages : 224
Détails du profil
Informations personnelles :
Âge : 38
Localisation : France, Haute Vienne (Limousin)

Informations forums :
Inscription : mai 2007
Messages : 224
Points : 45
Points : 45
Par défaut modification de programme .pc sous unix

Bonjour,

Je dois modifier plusieurs programmes sous UNIX (ajouter des lignes après certaines commandes). comment puis-je faire pour automatiser ces modifications ?
gege87270 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/09/2007, 16h44   #2
Modérateur
 
Avatar de gangsoleil
 
R&D en systemes informatiques bas niveau Unix/Linux
Inscription : mai 2004
Messages : 5 499
Détails du profil
Informations personnelles :
Âge : 31
Localisation : France, Isère (Rhône Alpes)

Informations professionnelles :
Activité : R&D en systemes informatiques bas niveau Unix/Linux

Informations forums :
Inscription : mai 2004
Messages : 5 499
Points : 9 679
Points : 9 679
Bonjour,

Il nous faut plus d'informations si tu veux que l'on puisse t'aider !
  • Est-ce que les commandes que tu cherches sont toujours les mêmes ?
  • Combien y en a-t-il ?
  • Est-ce que les lignes que tu souhaites ajouter sont toujours les mêmes ?
  • Est-ce que les fichiers cibles sont tous au même endroit ?
  • ...

Sinon, saches que

Code :
sed 's/chaine_a_remplacer/nouvelle_chaine/g' fichier_origine > nouveau_fichier
permet de créer un fichier "nouveau_fichier" qui sera une copie de "fichier origine" dans lequel on a remplacé "chaine_a_remplacer" par "nouvelle_chaine"

Donc en mettant quelques commandes de ce type dans un script, cela devrait te permettre de résoudre ton problème.
__________________
Modérateur "C", "Informatique Générale & Hardware" et "Unix"
Les règles du forum
gangsoleil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/09/2007, 16h57   #3
Membre du Club
 
Avatar de gege87270
 
Inscription : mai 2007
Messages : 224
Détails du profil
Informations personnelles :
Âge : 38
Localisation : France, Haute Vienne (Limousin)

Informations forums :
Inscription : mai 2007
Messages : 224
Points : 45
Points : 45
En fait on m'a parlé de l'outil awk pour faciliter les modif.

L'idée générale :

j'ai X fichiers (tous sous le même répertoire), qui contiennent des lignes de commandes (en pro*c) et je dois rajouter à la suite de ces lignes une ligne de commande supllémentaire (toujours la même).

Je sais pas si c'est clair, cà à l'air simple comme ça mais ???????
gege87270 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/09/2007, 21h57   #4
Membre Expert
 
Avatar de jlliagre
 
Inscription : juin 2007
Messages : 969
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juin 2007
Messages : 969
Points : 1 376
Points : 1 376
C'est pas encore très précis.

Qu'est ce que tu entends pas "à la suite" ?

A la fin de chacune des lignes de commande recherchées ?
Après le groupe de lignes recherché ?
A la fin des fichier contenant ces commandes ?
jlliagre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/09/2007, 23h37   #5
LLB
Membre Expert
 
Inscription : mars 2002
Messages : 946
Détails du profil
Informations forums :
Inscription : mars 2002
Messages : 946
Points : 1 085
Points : 1 085
Code :
echo "message" >> fichier.txt
permet d'ajouter une ligne à la fin d'un fichier.

Code :
1
2
3
for i in *; do
  echo "message" >> fichier.txt
done
pour ajouter la ligne à tous les fichiers du répertoire courant (*).

C'est ça que tu veux ?
LLB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/09/2007, 08h18   #6
Membre du Club
 
Avatar de gege87270
 
Inscription : mai 2007
Messages : 224
Détails du profil
Informations personnelles :
Âge : 38
Localisation : France, Haute Vienne (Limousin)

Informations forums :
Inscription : mai 2007
Messages : 224
Points : 45
Points : 45
OK,

Je vais te décrire un exemple de ce que je veux réaliser.

j'ai plusieurs fichier .pc (a.pc, b.pc...)

dans ces fichier j'ai une ligne
qui se trouve dans le corps des fichiers

je veux ajouter après cette ligne
un autre exemple

J'ai une ligne
Code :
EXEC SQL INCLUDE sqlca.h;
et je veux ajouter après cette ligne
Code :
1
2
 
EXEC SQL INCLUDE bmtmain.h;
et ainsi de suite

Le fait est que j'ai énormément de fichiers à traiter, et que j'ai beaucoup de ligne à ajouter. Je pourrais le faire manuellement, mais c'est au risque d'oublier certaines lignes voire certains fichiers. C'est pourquoi je voudrais créer des scripts qui me permettent de faire ces ajouts sans erreur.

j'espère que tu pourras m'éclairer...
gege87270 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/09/2007, 11h44   #7
Membre Expert
 
Avatar de jlliagre
 
Inscription : juin 2007
Messages : 969
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juin 2007
Messages : 969
Points : 1 376
Points : 1 376
Essaye ça:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
if [ ! -f pc-org.tar ]
then
  tar cf pc-org.tar *.pc || exit
fi
for file in *.pc
do
  cp $file $file.org
  awk '
/#include <gestimpr.h>/ {
  print $0
  print "#include <userprog.h>"
  continue
}
/EXEC SQL INCLUDE sqlca.h;/ {
  print $0
  print "EXEC SQL INCLUDE bmtmain.h;"
  continue
}
{
  print $0
}
' < $file.org > $file
done
jlliagre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/09/2007, 12h25   #8
LLB
Membre Expert
 
Inscription : mars 2002
Messages : 946
Détails du profil
Informations forums :
Inscription : mars 2002
Messages : 946
Points : 1 085
Points : 1 085
Code :
sed -i 's/#include <gestimpr.h>/&\n#include<userprog.h>/' *.pc
Code :
sed -i 's/EXEC SQL INCLUDE sqlca.h;/&\nEXEC SQL INCLUDE bmtmain.h;' *.pc
LLB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/09/2007, 13h32   #9
Membre Expert
 
Avatar de jlliagre
 
Inscription : juin 2007
Messages : 969
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juin 2007
Messages : 969
Points : 1 376
Points : 1 376
Attention, "sed -i" n'est pas à ma connaissance portable (spécifique Gnu sed).
Il est cependant simple de passer par des fichiers temporaires comme je l'ai fait avec awk.

D'autre part, il est possible de faire toutes les modifs avec une seule commande sed:
Code :
1
2
3
4
 
sed \
-e 's/#include <gestimpr.h>/&\n#include<userprog.h>/' \
-e 's/EXEC SQL INCLUDE sqlca.h;/&\nEXEC SQL INCLUDE bmtmain.h;' file.pc
jlliagre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/09/2007, 14h09   #10
LLB
Membre Expert
 
Inscription : mars 2002
Messages : 946
Détails du profil
Informations forums :
Inscription : mars 2002
Messages : 946
Points : 1 085
Points : 1 085
J'ai cru comprendre qu'il souhaitait deux commandes distinctes (vu que l'une parle de C et l'autre de SQL).

Et en effet, encore que de nombreux autres sed possèdent cette option (par exemple, le sed de BSD), l'option -i n'est pas portable. Mais si l'on veut être portable, il faut aussi se passer du \n, qui n'est pas reconnu partout.

Code :
1
2
3
sed '/#include <gestimpr.h>/a\
#include<userprog.h>\
'
(à condition encore, d'avoir un shell décent... sinon, il faut passer par un fichier...)

Mais je trouve que le sed défini par posix est bien trop limité pour l'usage quotidien, et j'ai pris l'habitude d'utiliser les extensions de GNU. Je recommande d'ailleurs aux gens d'utiliser le GNU sed (ou autre sed de qualité) quand ils ont le choix. En utilisant des sed de mauvaise qualité, on passe à côté de beaucoup de choses utiles (option -i, caractères spéciaux et de nombreuses autres extensions).
LLB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/09/2007, 18h49   #11
Membre Expert
 
Avatar de jlliagre
 
Inscription : juin 2007
Messages : 969
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juin 2007
Messages : 969
Points : 1 376
Points : 1 376
Citation:
Envoyé par LLB Voir le message
J'ai cru comprendre qu'il souhaitait deux commandes distinctes (vu que l'une parle de C et l'autre de SQL).
pro*c, comme d'autres (sql-c) est un langage préprocessé qui inclus les deux syntaxes au sein de même fichiers source. http://fr.wikipedia.org/wiki/Pro*C
Citation:
Et en effet, encore que de nombreux autres sed possèdent cette option (par exemple, le sed de BSD), l'option -i n'est pas portable. Mais si l'on veut être portable, il faut aussi se passer du \n, qui n'est pas reconnu partout.
"\n" est reconnu par les sed POSIX compliants.
Citation:
(à condition encore, d'avoir un shell décent... sinon, il faut passer par un fichier...)
Ce n'est pas le shell mais sed qui traite '\n' dans le cas décrit.

Citation:
Mais je trouve que le sed défini par posix est bien trop limité pour l'usage quotidien, et j'ai pris l'habitude d'utiliser les extensions de GNU. Je recommande d'ailleurs aux gens d'utiliser le GNU sed (ou autre sed de qualité) quand ils ont le choix. En utilisant des sed de mauvaise qualité, on passe à côté de beaucoup de choses utiles (option -i, caractères spéciaux et de nombreuses autres extensions).
Ca se discute.
jlliagre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/09/2007, 22h09   #12
Membre expérimenté
 
Avatar de BlaireauOne
 
Inscription : mars 2007
Messages : 469
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2007
Messages : 469
Points : 576
Points : 576
Petite rectification dans le awk :
Mettre next au lieu de continue
+ test pour éviter d'insérer plusieurs fois la même ligne

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
for file in *.pc
do
  cp $file $file.org

  awk '
      /#include <gestimpr.h>/ {
          print $0
          getline
          if ($0 != "#include <userprog.h>") {
              print "#include <userprog.h>"
          }
          print $0
          next
      }
      /EXEC SQL INCLUDE sqlca.h;/ {
          print $0
          getline
          if ($0 != "EXEC SQL INCLUDE bmtmain.h;") { 
              print "EXEC SQL INCLUDE bmtmain.h;"
          }
          print $0
          next
      }
  {
  print $0
  }
  ' $file.org > $file
done
__________________
Loi de Murphy:
La Théorie c'est quand ça ne marche pas mais que l'on sait pourquoi.
La Pratique c'est quand ça marche mais qu'on ne sait pas pourquoi.
Quand la théorie rejoint la pratique ça ne marche pas et on ne sait pas pourquoi.
BlaireauOne est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/09/2007, 08h49   #13
Membre Expert
 
Avatar de jlliagre
 
Inscription : juin 2007
Messages : 969
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juin 2007
Messages : 969
Points : 1 376
Points : 1 376
[QUOTE=BlaireauOne;2528120]Petite rectification dans le awk :
Mettre next au lieu de continue
+ test pour éviter d'insérer plusieurs fois la même ligne [/code]

Heu ... tu ajoutes une complexité inutile. Les deux patterns ne risquent pas d'apparaitre sur la meme ligne donc next est ici inutile.
Il faut laisser continue qui sert justement à éviter d'insérer plusieurs fois la meme ligne.
jlliagre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/09/2007, 10h07   #14
Membre du Club
 
Avatar de gege87270
 
Inscription : mai 2007
Messages : 224
Détails du profil
Informations personnelles :
Âge : 38
Localisation : France, Haute Vienne (Limousin)

Informations forums :
Inscription : mai 2007
Messages : 224
Points : 45
Points : 45
Merci à tous pour vos indications. Le moins qu'on puisse dire, c'est que mon cas fait débat...

Je vais essayer de m'y retrouver dans tous cela.
gege87270 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/09/2007, 10h59   #15
Membre du Club
 
Avatar de gege87270
 
Inscription : mai 2007
Messages : 224
Détails du profil
Informations personnelles :
Âge : 38
Localisation : France, Haute Vienne (Limousin)

Informations forums :
Inscription : mai 2007
Messages : 224
Points : 45
Points : 45
Est-ce qu'il ne faut pas intégrer BEGIN et END dans le script
if [ ! -f pc-org.tar ]
then
tar cf pc-org.tar *.pc || exit
fi
for file in *.pc
do
cp $file $file.org
awk ' BEGIN
/#include <gestimpr.h>/ {
print $0
print "#include <userprog.h>"
continue
}
/EXEC SQL INCLUDE sqlca.h;/ {
print $0
print "EXEC SQL INCLUDE bmtmain.h;"
continue
}
{
print $0
}
END
' < $file.org > $file
done
gege87270 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/09/2007, 17h38   #16
Membre Expert
 
Avatar de jlliagre
 
Inscription : juin 2007
Messages : 969
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juin 2007
Messages : 969
Points : 1 376
Points : 1 376
Il ne sert à rien d'inclure un BEGIN et un END s'il n'y a aucune instruction a exécuter en debut ou in fin de traitement.

Pour répondre à ta question envoyée en message privé, le premier bloc d'instructions sert juste à faire un backup des fichiers originaux:
Code :
1
2
3
4
5
6
7
8
9
10
11
 
# si le fichier pc-org.tar n'existe pas
if [ ! -f pc-org.tar ]
then
  # on crée l'archive tar contenant tous
  # les fichiers ayant l'extension .pc du répertoire courant.
  # Si cette création d'archive échoue, on abandonne le script car
  # on n'a vraisemblablement pas le droit d'écrire dans le répertoire
  # courant, ou le disque est plein, etc ...
  tar cf pc-org.tar *.pc || exit
fi
jlliagre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/09/2007, 22h07   #17
Membre expérimenté
 
Avatar de BlaireauOne
 
Inscription : mars 2007
Messages : 469
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2007
Messages : 469
Points : 576
Points : 576
[QUOTE=jlliagre;2528621]
Citation:
Envoyé par BlaireauOne Voir le message
Petite rectification dans le awk :
Mettre next au lieu de continue
+ test pour éviter d'insérer plusieurs fois la même ligne [/code]

Heu ... tu ajoutes une complexité inutile. Les deux patterns ne risquent pas d'apparaitre sur la meme ligne donc next est ici inutile.
Il faut laisser continue qui sert justement à éviter d'insérer plusieurs fois la meme ligne.
D'après la doc et ma pratique,
- "continue" fait passer à l'itération suivante dans une boucle (je ne vois pas de boucle while ou autre dans le awk qui nous occupe )
- "next" sert à retourner au début de la procédure awk et passer à l'enreg. suivant.
Je t'accorde que le test de présence d'enregistrements en doublon ajoute une complexité inutile (c'était pour montrer les possibilités de awk)


http://www.shellunix.com/awk.html#break
break, continue
Break: sortie de boucle
Continue: commence une nouvelle itération de la boucle.
.../...
next, exit
Next: passe à l'enregistrement suivant. On reprend le script awk à son début
Exit: ignore le reste de l'entrée et execute les actions définie par END
__________________
Loi de Murphy:
La Théorie c'est quand ça ne marche pas mais que l'on sait pourquoi.
La Pratique c'est quand ça marche mais qu'on ne sait pas pourquoi.
Quand la théorie rejoint la pratique ça ne marche pas et on ne sait pas pourquoi.
BlaireauOne est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/09/2007, 23h27   #18
Membre Expert
 
Avatar de jlliagre
 
Inscription : juin 2007
Messages : 969
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juin 2007
Messages : 969
Points : 1 376
Points : 1 376
Tu as raison. J'ai utilisé une construction archaique qui ne fonctionne qu'avec les awk originaux (awk et nawk sous Solaris par exemple, ou gawk --traditional) . Les continue doivent etre remplacés par des next dans mon script pour plus de portabilité via une conformité POSIX.
jlliagre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/09/2007, 08h56   #19
Membre du Club
 
Avatar de gege87270
 
Inscription : mai 2007
Messages : 224
Détails du profil
Informations personnelles :
Âge : 38
Localisation : France, Haute Vienne (Limousin)

Informations forums :
Inscription : mai 2007
Messages : 224
Points : 45
Points : 45
Coucou les gars,

J'ai bien pris note de toutes vos remarques et j'ai essayé de tester si le awk fonctionné sur un fichier.

J'ai donc un fichier test.pc et j'ai créé un .sh dans lequel j'ai mit le code suivant.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
for file in test.pc
do
  cp $file $file.org
  awk '
/#include <gestimpr.h>/ {
  print $0
  print "#include <userprog.h>"
  next
}
/EXEC SQL INCLUDE sqlca.h;/ {
  print $0
  print "EXEC SQL INCLUDE bmtmain.h;"
  next
}
/char TcSortie[80];/ {
  print $0
  print "char lib_err1[2000];"
  next
}
/EXEC SQL BEGIN DECLARE SECTION;/ {
  print $0
  print "VARCHAR sessionid[21],"
  print "lib-err[2000],"
  print "paragraphe_err[80];"
  print "int cd_ret;"
}
{
  print $0
}
' 
< $file.org > $file
done
Résultat, le programme boucle et ne produit rien si ce n'est que je me retrouve avec des ^M à la fin de chaque ligne de mon programme test.pc. Je ne comprend pas. Est-ce que c'est modif sont du au transfert FTP que j'ai fait ?

Avez vous une piste.

Merci
gege87270 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/09/2007, 09h07   #20
Membre Expert
 
Avatar de jlliagre
 
Inscription : juin 2007
Messages : 969
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juin 2007
Messages : 969
Points : 1 376
Points : 1 376
Quel Unix utilises-tu ?

Il est très simple de supprimer ces ^M.

Qu'entend-tu par "boucle et ne produit rien" ?

Utilise les tags "code" pour que ton code soit plus lisible.

Il manque un next dans ton avant dernier bloc.

Le < est inutile et le nom du fichier doit apparaitre après le ' final, sur la meme ligne, pas la ligne suivante.
jlliagre est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h59.


 
 
 
 
Partenaires

Hébergement Web