web-dev-qa-db-fra.com

Remplacer toutes les lignes entre deux modèles (inclus) par un contenu de fichier

Tout est dit dans le titre, je veux remplacer toutes les lignes entre deux modèles par un contenu de fichier.

fichier1

line 1
line 2
foo
foobar
bar
line 6
line 7

fichier2

line 3
line 4
line 5

fichier souhaité

line 1
line 2
line 3
line 4
line 5
line 6
line 7

Essayé de nombreuses commandes sed, rien ne fonctionne pour moi. La commande la plus proche ci-dessous correspond parfaitement aux lignes entre foo et bar, mais les remplace par la chaîne "$ (cat file2)" et non le contenu du fichier.

sed '/foo/{:a;N;/bar/!ba;N;s/.*\n/$(cat file2)/};p' file1
3
storm

Vous êtes proche, je pense - votre problème principal est que $(cat file2) va être traité littéralement entre guillemets - vous devriez utiliser la commande intégrée r:

r filename

Mettre en file d'attente le contenu du nom de fichier à lire et à insérer dans le flux de sortie à la fin du cycle en cours ou lors de la lecture de la ligne d'entrée suivante. Notez que si le nom de fichier ne peut pas être lu, il est traité comme s'il s'agissait d'un fichier vide, sans indication d'erreur.

Alors:

sed '
  /foo/{
    :a
    N
    /\nbar$/!ba
    r file2
    d
  }
' file1

Si vous souhaitez intégrer cela dans une seule ligne, vous devez éviter à sed de tout traiter après le r dans le nom du fichier:

sed -e '/foo/{:a; N; /\nbar$/!ba; r file2' -e 'd;}' file1
3
steeldriver