Sostituisci la stringa con il contenuto di un file usando sed


23

Ho due file diversi:

file1

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

file2

<TEXT1>
<TEXT2>

Voglio sostituire il <TEXT1>di File2 con il contenuto di File1 utilizzando sed. Ho provato questo comando, ma non ho ottenuto l'output corretto:

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

Puoi usare altri strumenti anche per risolvere questo problema.


Si prega di incollare quel messaggio di errore in modo che possiamo localizzarne l'origine. Dicci anche quale sedimplementazione stai usando. Il tuo codice funziona per me con GNU sed.
arte

Siamo spiacenti, non viene visualizzato un errore. Non sto ottenendo l'output desiderato. L'output è simile /home/user1/ n/home/user2/bin n/home/user1/a/b/cn <TEXT2>. Non ottenere nuove linee.
chanchal1987,

Non sono sicuro se questo si applicherebbe nel tuo caso specifico, ma con diffe gli patchstrumenti consentono di sostituire alcune linee in un file con altre linee abbastanza facilmente.
Stéphane Gimenez,

1
A proposito, l'uso di dati casuali raccolti $()in uno script sed mi fa sanguinare gli occhi. Non utilizzare mai dati esterni in luoghi in cui alcuni caratteri vengono interpretati con un significato speciale.
Stéphane Gimenez,

Risposte:


24

Ecco una soluzione di script sed (più facile per gli occhi che cercare di inserirlo in una riga della riga di comando):

/<TEXT1>/ {
  r File1
  d
}

Eseguendolo:

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

Grazie sta funzionando. Ma non voglio usare nessun altro file di script. Ci sono soluzioni in linea?
chanchal1987,

Certo:, sed '/<TEXT1>/{rFile1^Md^M}' File2dove "^ M" sta premendo Invio. Il problema è che sed ha davvero bisogno delle nuove righe all'interno di {...} per delimitare il comando re d.
Kusalananda

6
con bash, le stringhe in stile posix sono un po 'più pulite:sed $'/<TEXT1>/ {r File1\n d}'
glenn jackman,

9
Anche con -e per un liner:sed -e '/<TEXT1>/{r File1' -e 'd}' File2
sdaau,

1
E se invece di sostituire l'intera riga contenente <TEXT1>, voglio solo sostituire la stringa stessa, lasciando intatto il resto della riga? Text1: <TEXT1>a Text1: <file_contents>.
Robin Winslow,

9

Mi ci è voluto molto tempo per trovare questa soluzione usando la sostituzione var. Tutte le soluzioni sed non hanno funzionato per me, poiché eliminano le linee complete o le sostituiscono in modo errato.

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

Sostituisce tutte le occorrenze di TEXT1 in file2 con il contenuto di file1. Tutto il resto del testo rimane intatto.


molto bella. forse più veloce di sedtroppo, dal momento che quelle "espansioni" (ovvero i rimpiazzi) sono integrate nella shell ( bashalmeno)
giallo-tenue

7

Rispondo perché il metodo diff/ patchpotrebbe essere di interesse in alcuni casi. Per definire una sostituzione delle linee contenute nel file blob1con le linee contenute in blob2uso:

diff -u blob1 blob2 > patch-file

Ad esempio, se blob1contiene:

hello
you

e blob2contiene:

be
welcome
here

il generato patch-filesarà:

--- 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

Ora puoi applicare questa patch a qualsiasi altro file:

patch somefile patch-file

Essa sostituirà hello, youle linee di be, welcome, herelinee in somefile.


è davvero intelligente, ma sarebbe meglio se tu potessi automatizzarlo in una sceneggiatura
qodeninja,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.