Problème substitution avec ed /old/new/[gp]

gnugo -  
 gnugo -
Bonjour,

En utilisant la substitution par expression régulière de ed, je voudrais en une seule fois matcher une chaine selon un critère et modifier son contenu si cela correspond :
Cela va s'appliquer sur une liste de noms de fichiers avec leur chemin,
j'ai besoin de modifer certains fichiers selon leur nom, ce qui donne la chaine suivante :

/.*\/nomfichier$/\/nouveauchemin\/nomfichier/

donc /tmp/essai/nomfichier donne /nouveauchemin/nomfichier

Sauf qu'il me faut aussi l'ancien chemin dans le nouveau nom, sous la forme : /nouveauchemin/tmp-essai-nomfichier

Mais comment à la fois matcher un nom particulier et remplacer tous les '/' par des '-' ?

Je ne vois pas comment faire, je peux récupérer l'expression matchée avec &, mais il me faut ensuite faire un traitement sur &

ps : Si je suis limité à une seule substitution, c'est parce que j'utilise en fait pax avec l'option -s, qui substitue les noms de fichiers avec la même syntaxe que ed

Merci

2 réponses

  1. zipe31 Messages postés 34620 Date d'inscription   Statut Contributeur Dernière intervention   6 501
     
    Salut,

    Il suffit juste de matcher le "motif" voulu et d'opérer une substitution sur le chemin (en changeant le délimiteur par défaut, le slash (/) par un caractère quelconque, ici le point-virgule (;)) :

    $ cat plop 
    /home/moi/documents/fich.txt
    /home/moi/documents/toto.jpg
    /home/moi/documents/tata.pdf
    
    $ ed -s plop <<<$'/toto.jpg/ s;/.*/;/mnt/brol/archive/;\n,p'
    /home/moi/documents/fich.txt
    /mnt/brol/archive/toto.jpg
    /home/moi/documents/tata.pdf
    
    $ 

    ;-))
    0
  2. gnugo
     
    Salut et merci,

    Mais je n'ai pas bien compris pourquoi tu changes le délimiteur par défaut par le ; ?

    En fait ce que je cherche à obtenir c'est
    /home/moi/documents/fich.txt
    /mnt/brol/archive/-home-moi-documents-toto.jpg
    /home/moi/documents/tata.pdf
    0
    1. zipe31 Messages postés 34620 Date d'inscription   Statut Contributeur Dernière intervention   6 501
       
      Mais je n'ai pas bien compris pourquoi tu changes le délimiteur par défaut par le ; ?
      Juste pour ne pas être embêté avec trop d'anti-slash et de slash indigestes ;-))

      $ ed -s plop <<<$'/toto.jpg/ s|/|-|g\n/toto/s|.*|/mnt/brol/archive/&|\n,p'
      /home/moi/documents/fich.txt
      /mnt/brol/archive/-home-moi-documents-toto.jpg
      /home/moi/documents/tata.pdf
      
      $
      0
    2. gnugo
       
      eh bien merci ! :-)
      Je vais voir comment adapter ça au -s de pax
      0
    3. gnugo
       
      Le $' ' signifie quoi au juste ?
      0
    4. zipe31 Messages postés 34620 Date d'inscription   Statut Contributeur Dernière intervention   6 501
       
      C'est la syntaxe propre à la redirection (<<<). Ça sert à faire interpréter à "ed" ce qui se trouve entre les quotes simples.

      Pour toi ce qui importe c'est juste la syntaxe qui se trouve entre ces quotes :
      /toto.jpg/ s|/|-|g\n/toto/s|.*|/mnt/brol/archive/&|\n
      0
    5. gnugo
       
      Ok je vois le $' ' interprète certains caractères comme le \n
      Donc tu fais bien 2 commandes de substitution. |/|-|g et .*|/mnt/brol/archive/&|

      Hélas c'est inapplicable pour moi car je l'utilise avec pax : pax -s "/old/new/g"
      Je peux préciser plusieurs -s, mais il s'arrête à la première substitution réussie

      C'est pour ça que je cherche à le faire en une seule fois, et que je suis venu chercher de l'aide ici
      :-(
      0