Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1225 connectés 

  FORUM HardWare.fr
  Linux et OS Alternatifs
  Codes et scripts

  [BASH] remplacer des adresses par le contenu des fichiers

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[BASH] remplacer des adresses par le contenu des fichiers

n°1479801
hokutonofr​ed
Posté le 29-11-2022 à 15:59:46  profilanswer
 

Bonjour,
 
j'ai un fichier "maitre" qui appelle différents fichiers "auxiliaires" et je souhaiterai copier automatiquement le contenu des fichiers auxiliaires dans le fichier maitre.
 
C'est à dire que le contenu du fichier maitre est actuellement le suivant

Citation :

blablabla
blablabla
     APPELLE 'DONNES/fichier1.aux'
     APPELLE 'DONNES/fichier2.aux'
blablabla
blablabla
blablabla
     APPELLE 'DONNES/fichier3.aux'
     APPELLE 'DONNES/fichier4.aux'
     APPELLE 'DONNES/fichier5.aux'
blablabla
blablabla


Et je voudrai que toutes les lignes...

Citation :

    APPELLE 'DONNES/fichierX.aux'


...soient remplacées par le contenu du fichier en question afin d'obtenir un nouveau_fichier_maitre qui contienne:

Citation :

blablabla
blablabla
     [contenu du fichier1.aux]
     [contenu du fichier2.aux]
blablabla
blablabla
blablabla
     [contenu du fichier3.aux]
     [contenu du fichier4.aux]
     [contenu du fichier5.aux]
blablabla
blablabla


 
 
J'ai bidouillé un script en BASH pour établir la liste des appels des fichiers auxiliaires ...

Citation :

grep "^ APPELLE" fichier_maitre > APPELS.list


 
... puis je nettoie la liste ...

Citation :

cat APPELS.list | while read ligne
do
sed 's/ APPELLE //' | cut -c 2- | cut -f1 -d "'"
done


 
afin d'obtenir le listing "propre" des adresses  

Citation :

DONNES/fichier1.aux
DONNES/fichier2.aux
DONNES/fichier3.aux
DONNES/fichier4.aux
DONNES/fichier5.aux


 
 
Mais je ne sais pas comment :  
 
- stocker les adresses propres dans une variable  
Quand je fais  

Citation :

FICHIER=`sed 's/ APPELLE //' | cut -c 2- | cut -f1 -d "'"`


Le script crache un message d'erreur.
J'ai l'impression que c'est parce que la commande n'est plus à la suite du cat/while
 
- copier le contenu complet d'un fichier dans un autre sans écraser le contenu de celui-ci
J'avais dans l'idée de faire qq chose comme  

Citation :

cat APPELS.list | while read ligne
do
FICHIER=`sed 's/ APPELLE //' | cut -c 2- | cut -f1 -d "'"`
sed 's/$ligne/[ContenuDuFICHIER]/' fichier_maitre
done


mais visiblement c'est mal parti...  :pt1cable:  
 
Bref, je suis preneur de tout conseil pour transformer ce bricolage en script tout rutilent.  :D  


---------------
Quand Chuck Norris te répond "Dans ton cul", vérifie...
mood
Publicité
Posté le 29-11-2022 à 15:59:46  profilanswer
 

n°1479807
kajoux
Posté le 29-11-2022 à 17:33:35  profilanswer
 

while IFS='' read -r line; do
  if [[ $line =~ APPELLE\ \'([^\']+)\' ]]; then
    cat "${BASH_REMATCH[1]}"
  else
    echo "$line"
  fi
done <fichier_maitre >nouveau_fichier_maitre


Message édité par kajoux le 29-11-2022 à 17:34:03
n°1479808
hokutonofr​ed
Posté le 29-11-2022 à 17:37:38  profilanswer
 

Je comprends pas tout  :D  mais je testerai ça demain.

 

Merci pour la proposition.  :jap:


---------------
Quand Chuck Norris te répond "Dans ton cul", vérifie...
n°1479809
kajoux
Posté le 29-11-2022 à 17:43:42  profilanswer
 

Ça ne marchera qu'avec bash, et à condition que la syntaxe que tu donnes pour l'inclusion de fichiers soit respectée (APPELLE 'DONNES/fichier1.aux').
Sinon il faut adapter la regex.
Pour plus de lisibilité et d'adaptabilité, tu peux faire :

regex="APPELLE '([^']+)'"
while IFS='' read -r line; do
  if [[ $line =~ $regex ]]; then
    cat "${BASH_REMATCH[1]}"
  else
    echo "$line"
  fi
done <fichier_maitre >nouveau_fichier_maitre

n°1479810
hokutonofr​ed
Posté le 29-11-2022 à 18:51:49  profilanswer
 

kajoux a écrit :

Ça ne marchera qu'avec bash, et à condition que la syntaxe que tu donnes pour l'inclusion de fichiers soit respectée (APPELLE 'DONNES/fichier1.aux').
Sinon il faut adapter la regex.
Pour plus de lisibilité et d'adaptabilité, tu peux faire :

regex="APPELLE '([^']+)'"
while IFS='' read -r line; do
  if [[ $line =~ $regex ]]; then
    cat "${BASH_REMATCH[1]}"
  else
    echo "$line"
  fi
done <fichier_maitre >nouveau_fichier_maitre



 
Je me rends compte que mon exemple est imparfait, car dans la réalité, le fichier maitre se présente ainsi:

Citation :

blablabla
blablabla
     APPELLE 'DONNES/fichier1.aux' ;
*     APPELLE 'DONNES/fichier2.aux' ;
blablabla
blablabla
blablabla
     APPELLE 'DONNES/fichier3.aux' ;
     APPELLE 'DONNES/fichier4.aux' ;
*     APPELLE 'DONNES/fichier5.aux' ;
blablabla
blablabla


 
Pour la prise en compte de l'espace et du point virgule en fin de ligne, ce doit être facile à adapter grâce à la 2ème version que tu m'as proposé (merci).
Je suppose qu'il me suffira de remplacer ' par ; à la fin de la définition de regex:

Citation :

regex="APPELLE '([^']+);"


 
Par contre, comment prendre en compte le fait que certains appels à des fichiers AUX soient désactivés par un caractère * de commentaire en début de ligne ?
A part expurger le fichier maitre avant d'exécuter le script, y a-t-il moyen sur la base de ta proposition, d'ignorer les lignes APPELLE qui commencent par un caractère * ?


Message édité par hokutonofred le 29-11-2022 à 18:53:49

---------------
Quand Chuck Norris te répond "Dans ton cul", vérifie...
n°1479811
kajoux
Posté le 29-11-2022 à 19:11:28  profilanswer
 

Il n'y a pas besoin de se soucier de la fin de ligne ici (et il ne faut pas enlever l'apostrophe fermante comme tu l'as fait en tout cas).
Par contre pour l'étoile au début, il y a deux possibilités :
* soit tu es sûr qu'il y a des espaces ensuite, alors il suffit de faire

regex="^[^*]+APPELLE '([^']+)'"


* soit il peut ne pas y avoir d'espace après, alors il faut faire

regex="^([^*]+|)APPELLE '([^']+)'"
while IFS='' read -r line; do
  if [[ $line =~ $regex ]]; then
    cat "${BASH_REMATCH[2]}"
  else
    echo "$line"
  fi
done <fichier_maitre >nouveau_fichier_maitre


Note le BASH_REMATCH[2] en plus de la modif supplémentaire de la regex.

n°1479812
kajoux
Posté le 29-11-2022 à 19:29:12  profilanswer
 

Ah ça n'est pas tout à fait bon car je suppose que tu ne veux pas afficher les lignes d'inclusion commençant par * dans le résultat final.
Donc le plus simple et lisible est de garder la regex de départ et de faire ça :

regex="APPELLE '([^']+)'"
while IFS='' read -r line; do
  if [[ $line =~ $regex ]]; then
    if [[ $line != \**  ]]; then
      cat "${BASH_REMATCH[1]}"
    fi
  else
    echo "$line"
  fi
done <fichier_maitre >nouveau_fichier_maitre

n°1479813
hokutonofr​ed
Posté le 29-11-2022 à 19:42:36  profilanswer
 

Si justement, je préfère garder les lignes commençant par * dans le fichier final. :)
Comme ça en comparant (par meld/tkdiff) le fichier original et le nouveau fichier qui inclut le contenu des fichiers AUX appelés, on voit tout de suite ce qui a été inclut, sans rien modifier d'autre.

 

Du coup je partirai plutôt sur ton avant-dernière proposition.
(enfin je pense que je vais tester un peu tout ça, demain, pour essayer de comprendre ce qu'il se passe ;) )

 

Merci pour le warning sur le numéro associé à BASH_REMATCH, je n'aurai peut être pas fait attention, en effet.


Message édité par hokutonofred le 29-11-2022 à 21:09:19

---------------
Quand Chuck Norris te répond "Dans ton cul", vérifie...
n°1479814
kajoux
Posté le 29-11-2022 à 19:46:12  profilanswer
 

Tout est dans man bash pour comprendre les syntaxes utilisées, en particulier =~ et BASH_REMATCH  :)

n°1479840
hokutonofr​ed
Posté le 30-11-2022 à 14:39:49  profilanswer
 

Merci kajoux.  :jap:  
 
J'ai appliqué cette méthode
 

Citation :

regex="^([^*]+|)APPELLE '([^']+)'"
while IFS='' read -r line; do
  if [[ $line =~ $regex ]]; then
    cat "${BASH_REMATCH[2]}"
  else
    echo "$line"
  fi
done <fichier_maitre >nouveau_fichier_maitre


 
et ça fonctionne nickel.


---------------
Quand Chuck Norris te répond "Dans ton cul", vérifie...

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Linux et OS Alternatifs
  Codes et scripts

  [BASH] remplacer des adresses par le contenu des fichiers

 

Sujets relatifs
erreur 500 lors du montage systeme fichiersRecherche dans des fichiers avec stat
Récupérer les adresse IP avec un script BashSystème de fichiers en lecture seule d'un seul coup
[Bash] Passer un argument dans l'execution d'une commande à distanceAide Script d'installation de service (bash)
[postgresql] fichiers wal et archivage continuUne alternative à JIRA , GIT + Bash ?
Scripts pour télécharger des fichiers .txt dans site web avec from 
Plus de sujets relatifs à : [BASH] remplacer des adresses par le contenu des fichiers


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR