Zamień wzór w pliku na zawartość innego pliku


20

Mam plik tekstowy ( devel.xml).

Dodałem do niego słowo REPLACETHIS, aby zastąpić ten ciąg treścią w innym pliku ( temp.txt).

Mam najbliższą rzecz:

sed -i -e "/REPLACETHIS/r temp.TXT" -e "s///" devel.txt;

Spowoduje to wstawienie treści po ciągu, a następnie usunięcie ciągu.

Czy to najlepszy sposób, aby to zrobić?


Czy to musi być sed? W zależności od ilości tekstu w temp.txt, mogę podejść do rozwiązania perla.
user17591,

Odpowiedzi:


34

To, co zrobiłeś, to usunąć SUBSTITUTETHISgdziekolwiek pojawi się w pliku (ale nie resztę wiersza, w którym się pojawia) i wstawić zawartość temp.TXTponiżej tego wiersza. Jeśli SUBSTITUTETHISpojawia się wiele razy w wierszu, usuwane jest tylko pierwsze wystąpienie i temp.TXTdodawana jest tylko jedna kopia .

Jeśli chcesz zastąpić cały wiersz, gdy się SUBSTITUTETHISpojawi, użyj dpolecenia. Ponieważ musisz biegać zarówno, jak ri dgdy jest mecz, umieść je w przygotowanej grupie.

sed -e '/SUBSTITUTETHIS/ {' -e 'r temp.TXT' -e 'd' -e '}' -i devel.txt

Niektóre implementacje sed pozwalają używać średników do oddzielania poleceń i całkowicie pomijają separatory wokół nawiasów klamrowych, ale nadal potrzebujesz nowej linii, aby zakończyć argument rpolecenia:

sed -e '/SUBSTITUTETHIS/ {r temp.TXT
                          d}' -i devel.txt

Jeśli chcesz zastąpić SUBSTITUTETHISzawartością pliku, ale zachować to, co jest przed i po nim w wierszu, jest to bardziej skomplikowane. Najprostszą metodą jest włączenie zawartości pliku do polecenia sed; pamiętaj, że będziesz musiał poprawnie zacytować jego zawartość.

sed -e "s/SUBSTITUTETHIS/$(<temp.TXT sed -e 's/[\&/]/\\&/g' -e 's/$/\\n/' | tr -d '\n')/g" -i devel.txt

Lub użyj Perla. Jest to krótkie, ale działa catraz dla każdej zmiany:

perl -pe 's/SUBSTITUTETHIS/`cat temp.TXT`/ge' -i devel.txt

Aby raz odczytać plik po uruchomieniu skryptu i unikać zależnie od polecenia powłoki:

perl -MFile::Slurp -pe 'BEGIN {$r = read_file("temp.TXT"); chomp($r)}
                        s/SUBSTITUTETHIS/$r/ge' -i devel.txt

(przedstawione w dwóch liniach dla czytelności, ale można pominąć podział linii). Jeśli nazwa pliku jest zmienna, aby uniknąć problemów z cytowaniem, przekaż ją do skryptu za pomocą zmiennej środowiskowej:

replacement_file=temp.TXT perl -MFile::Slurp -pe 'BEGIN {$r = read_file($replacement_file); chomp($r)}
                        s/SUBSTITUTETHIS/$r/ge' -i devel.txt

Jak mogę zmienić polecenie Perla, aby zamiast tego cat temp.txtmóc cat ${variable}?
Maria Ines Parnisari

@MariaInesParnisari Popełniłem błąd przy formatowaniu komentarza. Zobacz moją odpowiedź z nieco innym, bardziej niezawodnym rozwiązaniem.
Gilles 'SO - przestań być zły'

Ponieważ File :: Slurp nie zawsze jest instalowany, alternatywą jest użycie -0777przełącznika do slurp w całym pliku i regularne open:perl -0777 -pe 'BEGIN {open F, q(temp.TXT); $r=<F>; chomp($r)} s/SUBSTITUTETHIS/$r/ge' -i devel.txt
mivk

Jak zawijać r temp.TXTwiadomości typu „BEGIN temp.TXT”, „END temp.TXX”
Kyb

Znalazłem rozwiązanie dla mojego pytania. Użyj polecenia a(dodaj). grymoire.com/Unix/Sed.html#uh-36
kyb
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.