Comment remplacer plusieurs lignes en utilisant bash?

J’ai un fichier avec des milliers de lignes. Je cherche de l’aide pour modifier plusieurs lignes que je devais choisir.

Package: com.xyz.abc Version: 1.0 Filename: ./debs/abc.deb Package: com.xyz.def Version: 1.0.0-1 Filename: ./debs/def.deb 

J’ai besoin d’une commande bash pour détecter “Nom de fichier”, puis changez-les en quelque chose comme ceci:

 Package: com.xyz.abc Version: 1.0 Filename: ./debs/download.php?p=abc Package: com.xyz.def Version: 1.0.0-1 Filename: ./debs/download.php?p=def 

Et il va boucler jusqu’à ce que tous les “noms de fichiers” ont été modifiés.

C’est un travail pour sed ! De la page d’accueil GNU sed :

Sed est généralement utilisé pour extraire une partie d’un fichier en utilisant une correspondance de modèle ou en substituant plusieurs occurrences d’une chaîne dans un fichier.

Voici comment vous pouvez le faire:

 sed '/^Filename:/s!\(./debs/\)\(.*\).deb!\1download.php?p=\2!' /path/to/input > /path/to/output 

Où:

  • /^Filename:/ recherche les lignes commençant par ( ^ ) le texte ‘Nom de fichier:’
  • s!search!replace! remplace ‘search’ par ‘replace’ où ‘search’ est une expression régulière
  • \1 est la chaîne capturée par le premier groupe correspondant ” \(...\)
  • \2 est la chaîne capturée par le deuxième groupe correspondant ” \(...\)

Manifestation:

 $ echo 'Package: com.xyz.abc Version: 1.0 Filename: ./debs/abc.deb Package: com.xyz.def Version: 1.0.0-1 Filename: ./debs/def.deb' | sed '/^Filename:/s!\(./debs/\)\(.*\).deb!\1download.php?p=\2!' Package: com.xyz.abc Version: 1.0 Filename: ./debs/download.php?p=abc Package: com.xyz.def Version: 1.0.0-1 Filename: ./debs/download.php?p=def 

Pour modifier ceci et pour écrire vos propres scripts sed , veuillez consulter la documentation en ligne .

Ceci est une solution:

 perl -pi -e '/^Filename:/ and s,debs/([^.]+)\.deb\s*$,debs/download.php?p=$1,' thefile 

Essayez-le d’abord en ne le mettant pas en option et en utilisant less . Ensuite, rajoutez le i .

Pas en bash lui-même, mais:

 sed 's#Filename: \./debs/\(.*\)\.deb#Filename: ./debs/download.php?p=\1#' < the_file 

Vous recherchez un outil appelé sed :

 sed -e "s|^(Filename: ./debs/)(.+).deb|\1download.php?p=\2|" < yourfile 

Voici des réponses améliorées avec awk et sed .

À la différence des autres réponses, celles-ci fonctionnent indépendamment du chemin d’access au nom de fichier. C’est-à-dire que si vous modifiez «./debs/» en «./myDebs/», cela fonctionnera toujours. Tout ce dont ils ont besoin, c’est que le fichier ‘.deb’ se trouve à la fin du chemin

Sed

 sed '/Filename:/s|^\(.*/\)\([^\.]*\)\..*$|\1download.php?p=\2|' ./infile 

awk

 awk -F'/' '/Filename:/{split($NF,a,".");$NF="download.php?p=" a[1]}1' OFS='/' ./infile 

Consortingbution

 $ cat ./infile Package: com.xyz.abc Version: 1.0 Filename: ./debs/abc.deb Package: com.xyz.def Version: 1.0.0-1 Filename: ./MyDebs/def.deb 

sed output

 $ sed '/Filename:/s|^\(.*/\)\([^\.]*\)\..*$|\1download.php?p=\2|' ./infile Package: com.xyz.abc Version: 1.0 Filename: ./debs/download.php?p=abc Package: com.xyz.def Version: 1.0.0-1 Filename: ./MyDebs/download.php?p=def 

awk sortie

 $ awk -F'/' '/Filename:/{split($NF,a,".");$NF="download.php?p=" a[1]}1' OFS='/' ./infile Package: com.xyz.abc Version: 1.0 Filename: ./debs/download.php?p=abc Package: com.xyz.def Version: 1.0.0-1 Filename: ./MyDebs/download.php?p=def 

Cela pourrait fonctionner pour vous:

  sed '/^Filename:/s/\([^/]*\)\.[^.]*$/download.php?p=\1/' file