Remplacer la chaîne par le contenu d'un fichier à l'aide de sed


23

J'ai deux fichiers différents:

File1

/home/user1/  
/home/user2/bin  
/home/user1/a/b/c

File2

<TEXT1>
<TEXT2>

Je veux remplacer le <TEXT1>de File2 par le contenu de File1 en utilisant sed. J'ai essayé cette commande, mais je n'ai pas obtenu de sortie appropriée:

cat File2|sed "s/<TEXT1>/$(cat File1|sed 's/\//\\\//g'|sed 's/$/\\n/g'|tr -d "\n")/g"

Vous pouvez également utiliser d'autres outils pour résoudre ce problème.


Veuillez coller ce message d'erreur afin que nous puissions localiser sa source. Dites-nous également quelle sedimplémentation utilisez-vous. Votre code fonctionne pour moi avec GNU sed.
manatwork

Désolé, pas d'erreur. Je n'obtiens pas la sortie souhaitée. La sortie est comme /home/user1/ n/home/user2/bin n/home/user1/a/b/cn <TEXT2>. Pas de nouvelles lignes.
chanchal1987

Je ne sais pas si cela s'appliquerait dans votre cas spécifique, mais avec diffet les patchoutils permettent de remplacer assez facilement certaines lignes d'un fichier par d'autres lignes.
Stéphane Gimenez

1
Btw, en utilisant des données aléatoires recueillies $()dans un script sed me fait saigner les yeux. N'utilisez jamais de données externes dans des endroits où certains caractères sont interprétés avec une signification particulière.
Stéphane Gimenez

Réponses:


24

Voici une solution de script sed (plus facile à regarder que d'essayer de la mettre en une seule ligne sur la ligne de commande):

/<TEXT1>/ {
  r File1
  d
}

Exécuter:

$ sed -f script.sed File2
/home/user1/
/home/user2/bin
/home/user1/a/b/c
<TEXT2>

Merci, cela fonctionne. Mais je ne veux utiliser aucun autre fichier de script. Existe-t-il une solution en ligne?
chanchal1987

Bien sûr:, sed '/<TEXT1>/{rFile1^Md^M}' File2où "^ M" vous appuyez sur Entrée. Le problème est que sed a vraiment besoin des sauts de ligne dans le {...} pour délimiter les commandes r et d.
Kusalananda

6
avec bash, les cordes de style posix sont un peu plus propres:sed $'/<TEXT1>/ {r File1\n d}'
glenn jackman

9
Également avec -e pour un sed -e '/<TEXT1>/{r File1' -e 'd}' File2
aller simple

1
Et si au lieu de remplacer la ligne entière contenant <TEXT1>, je veux juste remplacer la chaîne elle-même, en laissant le reste de la ligne intact? Text1: <TEXT1>à Text1: <file_contents>.
Robin Winslow

9

Cela m'a pris beaucoup de temps pour trouver cette solution en utilisant le remplacement var. Toutes les solutions sed ne fonctionnaient pas pour moi, car elles supprimaient des lignes complètes ou remplaçaient incorrectement.

FILE2=$(<file2)
FILE1=$(<file1)
echo "${FILE2//TEXT1/$FILE1}" 

Remplace toutes les occurrences de TEXT1 dans le fichier2 par le contenu du fichier1. Tout autre texte reste intact.


très agréable. peut-être plus vite que sedtrop, car ces "extensions" (alias remplacements) sont intégrées dans la coque ( bashau moins)
jaune moelleux

7

Je réponds car la méthode diff/ patchpeut être intéressante dans certains cas. Pour définir une substitution des lignes contenues dans le fichier blob1par des lignes contenues dans l' blob2utilisation:

diff -u blob1 blob2 > patch-file

Par exemple, si blob1contient:

hello
you

et blob2contient:

be
welcome
here

le généré patch-filesera:

--- blob1   2011-09-08 16:42:24.000000000 +0200
+++ blob2   2011-09-08 16:50:48.000000000 +0200
@@ -1,2 +1,3 @@
-hello
-you
+be
+welcome
+here

Maintenant, vous pouvez appliquer ce patch à n'importe quel autre fichier:

patch somefile patch-file

Il remplacera hello, youlignes par be, welcome, herelignes somefile.


c'est vraiment intelligent mais ce serait mieux si vous pouviez l'automatiser dans un script
qodeninja
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.