Jak podzielić wyraz długiej sed na wiele linii?

15
sed 's/[long1][long2]/[long3][long4]/' file.txt

Chciałbym podzielić to polecenie na wiele linii - fx coś takiego:

sed 's/
    [long1]
    [long2]
  /
    [long3]
    [long4]
  /' file.txt

Używanie \lub rozdzielanie ciągów nie działało.

Raffael
źródło
Właśnie dlatego Perl ma /xmodyfikator do podstawienia.
choroba
1
@Networker: tak, dziękuję, tam też dodałem swoją odpowiedź
Raffael

Odpowiedzi:

8

Możesz zapisać długi ciąg do zmiennych bash, a następnie użyć w sedpoleceniu:

string=[long1][long2]
replace= [long3][long4]
sed -e 's/'"$string"'/'"$replace"'/' file

Jeśli możesz użyć perl, możesz przerwać długi wzór za pomocą xmodyfikatora:

perl -e 's/
[long1]
[long2]
/[long3][long4]/x' file
Cuonglm
źródło
1
Dlaczego używasz tak wielu cytatów? sed "s/$string/$replace/" file.txtjest w porządku.
Scott
1
Oczywiście po tym musisz usunąć spację replace=.
Scott
8
sed 's'/\
'[long1]'\
'[long2]'\
'/'\
'[long3]'\
'[long4]'\
'/' file.txt

Dzielenie kilku linii odwrotnym ukośnikiem działa, jeśli nowe linie nie są wcięte.

$ echo "a,b" | sed 's/\(.'\
> '\),\(.\)/\2-\1/'
b-a

Testowane na Cygwin z GNU sed 4.2.2

Raffael
źródło
Jaka jest twoja wersja sed? Testuję z GNU sed version 4.2.1i to nie działa.
cuonglm
2
Wygląda na to, że brakuje kreski ułamkowej na końcu pierwszej linii, po ukośniku?
Volker Siegel,
7

Kolejny aspekt:

Jak utrzymywalne są [long]powyższe elementy?

Im krótsze i bardziej wyraźne są klauzule, tym łatwiej będzie je zmieniać i ulepszać w miarę upływu czasu i (sed-zewnętrznych) faktów zmieniających się wokół funkcji, którą zapewniają.

na przykład

sed \
-e 's / [minimal-s1] / [minimal-r1] /' \
-e 's / [minimal-s2] / [minimal-r2] /' \
-e 's / [minimal-s3] / [minimal-r3] /' \
-e 's / [minimal-s4] / [minimal-r4] /' 

... może być czymś, do czego należy dążyć i preferować.

Hannu
źródło
4

Możesz to również rozbić w ten sposób:

sed '/[long1][long2]/
    s//[long3][long4]/'

A może jak:

sed "$(
    printf 's/[%s][%s]/[%s][%s]/' \
        long1 \
        long2 \
        long3 \
        long4
)"

Lub z heredoc:

sed -f - <<SED file.txt
s/\
[long1]\
[long2]\
/\
[long3]\
[long4]\
/
SED
mikeserv
źródło