Użycie tutaj-doc dla `sed` i pliku


10

Chcę użyć tutaj doc do poleceń sed i dostarczyć plik do odczytu i plik wyjściowy.

Przeglądałem Here-Documents z przewodnika Advanced Bash Scripting, ale nie wspomina nic o regularnych argumentach podczas korzystania z here-doc. Czy to w ogóle możliwe?

Chciałbym osiągnąć coś takiego:

#!/bin/bash
OUT=/tmp/outfile.txt
IN=/my_in_file.txt

sed $IN << SED_SCRIPT
    s/a/1/g
    s/test/full/g

SED_SCRIPT 
> $OUT;

Każda pomoc jest na prawdę doceniana.

Odpowiedzi:


14

Możesz powiedzieć GNU sed, aby odczytał skrypt ze standardowego wejścia -f -, -fco oznacza odczytanie skryptu z pliku, i oznaczenie -standardowego wejścia, jak to jest często w przypadku wielu poleceń.

sed -f - "$IN" > "$OUT" << SED_SCRIPT
    s/a/1/g
    s/test/full/g
SED_SCRIPT

POSIX sed obsługuje również -f, ale użycie -standardowego wejścia nie jest udokumentowane. W takim przypadku możesz użyć /dev/stdinna systemach Linux (i wydaje mi się, że pamiętam, że Solaris też to ma, ale nie mogę tego teraz potwierdzić)

Użycie <<-SED_SCRIPT(z prefiksem „-”) pozwoli na SED_SCRIPTwcięcie znacznika zamykającego .


Dziękuję, co powiedziałeś, działało, jakkolwiek chciałbym zauważyć, że token zamykający nie może być wcięty, w przeciwnym razie spowoduje błąd w bash, zakładam, że dzieje się tak, ponieważ zawiera on również spację w zamykającym.
Tristian

Pamiętaj, że Apple OS X sed nie obsługuje odczytu skryptu ze standardowego wejścia. (Przynajmniej nie w ten lub inny udokumentowany sposób.)
danorton

@danorton: I dodano do roztworu , który nie wymaga wsparcia -f -w sedale wymaga zmiany procesu: <( command ).
pabouk

5

W przypadku sednie obsługuje czytania skryptu od stdin(za pomocą -f -), można użyć podstawienia procesowego (dostępne w bash, zsh, ksh93):

sed "$IN" > "$OUT" -f <( cat << SED_SCRIPT
    s/a/1/g
    s/test/full/g
SED_SCRIPT)

Nawias zamykający )musi następować po znaku ogranicznika końca ( SEC_SCRIPT) natychmiast lub po nowej linii. W przypadku zastąpienia procesu możesz również użyć echozamiast dokumentu tutaj:

sed "$IN" > "$OUT" -f <( echo \
"    s/a/1/g
    s/test/full/g" )

1
W systemie Mac OS X nie podoba mu się plik wejściowy ( "$IN"a nawet testfile.txt) natychmiast po samej komendzie sed - chciał mieć -e scriptlub -f file. Ponowna aranżacja odpowiedzi @pabouk zadziałała dla mnie:sed -f <( cat << ETC ... ETC) "$IN" > "$OUT"
Stephen P

W Max OSX z wersją bash 4.2.45 i standardowym BSD sed, nawiasy zamykające musiały znajdować się w nowej linii poniżej zamknięcia SED_SCRIPT.
Alexander Klimetschek,

-1

Może ładniejsze podejście:

OUT=/dev/stdout

IN=my_in_file.txt
sed -s 's/in/out/' < $IN > $OUT
  -or-
sed -s 's/in/out/' > $OUT < $IN

IN=my_in_text
sed -s 's/in/out/' <<< $IN > $OUT
  -or-
sed -s 's/in/out/' > $OUT <<< $IN

:)


1
Ciekawe, ale poza tym. OP chce przekazywać komendy sed przez stdin.
muru

Takie podejście pozwala na obie metody, dlaczego głosowanie negatywne?
Magnus

Powtórz: „przekazuj komendy sed przez stdin”. Twoja odpowiedź nie robi tego żadną metodą.
muru
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.