Jest kilka sposobów na obejście tego w / sed
. Jednym ze sposobów jest opóźniony odczyt, zgodnie z zaleceniami przyjętej odpowiedzi. Można to również napisać w następujący sposób:
sed -e '$!N;P;/\nPointer/r file1' -e D file2
... z nieco wyraźnym spoglądaniem w przyszłość zamiast z tyłu zaimplementowanym gdzie indziej z buforem wstrzymania. Które będą mieć ten sam problem z ostatniej linii, która @don_crissti zauważa jednak, bo N
robi przyrost cykl linii i r
polecenia EAD jest stosowany przez numer linii.
Możesz obejść to:
echo | sed -e '$d;N;P;/\nPointer/r file1' -e D file2 -
Nie wszystkie sed
s zinterpretują -
standardowe wejście, ale wielu tak. ( POSIX mówi, że sed
powinien obsługiwać -
standard-in, jeśli implementator chce -
oznaczać standard-in ???)
Innym sposobem jest uporządkowanie dołączonej zawartości w kolejności. Istnieje inne polecenie, które planuje wyjście w taki sam sposób, jak r
robi to ead, i sed
zastosuje je i r
ead w kolejności, w jakiej są skrypty. Jest jednak trochę bardziej zaangażowany - wymaga użycia jednego, sed
aby a
dopasować Pointer
dopasowanie do wyniku innego sed
w swoim skrypcie.
sed ' /Pointer/!d #only operate on first match
s/[]^$&\./*[]/\\&/g;H #escape all metachars, Hold
s|.*|/&/!p;//!d|p;g #print commands, exchange
s|.|r file1&a\\&|;q' file2| #more commands, quit
sed -nf - file2 #same input file
Zasadniczo pierwszy sed
pisze drugi sed
skrypt, który drugi sed
odczytuje na standardowym wejściu (może ...) i stosuje z kolei. Pierwszy sed
działa tylko przy pierwszym dopasowaniu dla Pointer
znalezionego, a następnie q
wprowadza dane wejściowe. Jego zadaniem jest ...
s/[]^$&\./*[]/\\&/g;H
- Upewnij się, że wszystkie znaki wzorcowe są bezpiecznie odwrócone ukośnikiem, ponieważ drugi
sed
będzie musiał zinterpretować każdy fragment, który czyta dosłownie, aby go poprawnie. Gdy to zrobisz, umieść kopię w H
starej przestrzeni.
s|.*|/&/!p;//!d|p; x
- Powiedz drugiemu,
sed
aby p
zrewidował każdą linię wprowadzania, !
ale tę, /&/
którą właśnie zabezpiecziliśmy; a następnie d
usunąć to samo. p
zrewiduj polecenia po drugim sed
, a następnie x
zmień h
stary i bufor buforów wzorców, aby działały na naszej zapisanej kopii.
s|.|r file1&a\\&|p;q
- Jedynym char, z którym pracujemy tutaj, jest
\n
ewline, ponieważ sed
będzie poprzedzał jeden, gdy staraliśmy się H
o linię wcześniej. Więc wstawiamy polecenie r file1
i podążamy za nim z naszą \n
ewline, a następnie polecenie a\\
dla a
ppend, a następnie także \n
ewline. Cała reszta naszej H
linii eld jest zgodna z ostatnią \n
linią ewline.
Skrypt, który pierwszy pisze, wygląda mniej więcej tak:
/Pointer-file2 "23"/!p;//!d
r file1
a\
Pointer-file2 "23"
Zasadniczo drugi sed
wypisze każdą linię, ale ten pierwszy sed
ustawi ją na a
ppend. Dla tej konkretnej linii zaplanowano dwa opóźnione zapisy do standardowego wyjścia - pierwszy to ead, a drugi to kopia linii, którą chcemy po nim. Pierwsze doktorowanie nie jest nawet konieczne w tym przypadku (patrz? Żadnych odwrotnych ukośników), ale ważne jest, aby bezpiecznie uciec w sposób, w jaki tu robię, za każdym razem, gdy dopasowanie wzorca zostanie zmienione jako wejście.r
file1
sed
W każdym razie, więc ... jest kilka sposobów.