W tej edycji
Stéphane Chazelas POSIXify (ponownie) moje sed
formatowanie poprzez wstawienie -e
przerwy xpression i innej -e
instrukcji xpression. Teraz mogę go zapytać, dlaczego w komentarzach, ale przypuszczam, że jest to już numer 18 tej odpowiedzi i prawie wszystkie poprzednie były już dzięki podobnym gratisom (jeśli zobaczysz usunięte komentarze, będziesz wiedział, co Mam na myśli) . Myślę też, że jestem wystarczająco blisko, aby zrozumieć, dlaczego sformułować to w sposób, który może być bardziej ogólnie przydatny. Mam nadzieję, że ...
Generalnie wolę zachować moje całkowite sed
-e
xpressions do jednego, jeśli mogę, ale mam też większą ochotę na dostosowanie się do specyfikacji tak blisko, jak to możliwe, szczególnie gdy różnica wynosi nie więcej niż a <space>
i an -e
. Ale nie mogę tego zrobić, jeśli nie rozumiem, dlaczego powinienem. Oto krótkie podsumowanie obecnego stanu mojego zrozumienia:
' -e '
przerwa może przenośnie stanąć nased
skrypt\n
przerwie ewline wsed
oświadczeniu wiersza polecenia ... Jestem wprawdzie rozmyta, dlaczegonawias zamykający w
sed
{
funkcji}
musi być poprzedzony\n
przerwaniem ewline, jak podano tutaj:- Znak
<right-brace>
poprzedzony jest znakiem<newline>
a i może poprzedzać go lub następować po nim<blank>
znak.
- Znak
\n
przerwa ewline podobnie jest wymagane po każdym wykorzystaniu ...a
,b
,c
,i
,r
,t
,w
, lub:
.
Ale nie rozumiem jasno, w jaki sposób definicja {
funkcji }
odnosi się do !
operatora niebędącego operatorem. Jedyna wzmianka o operatorze negacji znajdująca się w specyfikacji:
- Funkcja może być poprzedzona jednym lub większą liczbą
!
znaków, w którym to przypadku funkcja zostanie zastosowana, jeśli adresy nie wybiorą przestrzeni wzorów.
Czy oznacza to, że stosowanie dokumentu !
zakłada {
szelki }
? Co z $!
poleceniami - czy powinny być one również oddzielone ' -e '
przerwami? Czy o to chodziło, kiedy Stéphane POSIXifikował ostatnio moją odpowiedź?
Myślę, że jest to albo !
operator negacji, albo b
wypowiedź rancza, do której odnosi się w swojej edycji - a może jest to jednocześnie naraz - ale nie wiem i chciałbym to zrobić. Jeśli jest to tylkob
oświadczenie ranczo, to wierzęd
zrobiłby na jego miejscu i wyeliminować potrzebę ' -e '
przerwie, ale wolałbym być pewny zanim hazarding trzykroć POSIXified odpowiedź. Możesz pomóc?
Zrobiłem ryzykować po wszystkim , ale nie z każdej wielkiej pewności ...
b;n;:b
rozgałęziasz się do etykiety o nazwie";n;:b"
seds historycznej i POSIX (a GNU sed nie jest pod tym względem).:
że jechałeś do domu kilka miesięcy temu. Ale nie do końca rozumiem, dlaczego drugiesed
polecenie było podobnie POSIXified .sed
jest dla mnie bardzo niejasna. W przeszłości kilkakrotnie prosiłem o wyjaśnienia, ale nie sądzę, aby w rezultacie został zaktualizowany. Dobrym testem jest wypróbowanie zestawu narzędzi dla potomków (Solaris, wywodzący się z oryginału, na którym w dużej mierze oparta jest specyfikacja POSIX).s///
utstitutions są w stanie zaakceptować tworzenie łańcuchów za pomocą ; . rozmywa się wokół poleceń, które muszą być oddzielone znakiem nowej linii, i jak-e
może stać w tym przypadku - przynajmniej dla mnie. natknąłem się jednak na coś,sed
co nie interpretuje ich dość zamiennie.;
przed nową linią - nowa linia jest w porządku. Szczerze mówiąc, to mógłby zrobić bez-e
i wszystko całkowicie i po prostu zapisać plik, jak#!/bin/sed
z każdego polecenia na nową linią - lub te, które nie wymagają takich ograniczników zamiast rozdzielone;
. Te, które zrobić wymagają nowej linii są zwykle te, które przyjmują dowolne wejście -:
nazwy etykiet i poleceń, które odnoszą się do nich jakb
lubt
czy zamykanie}
nawiasów klamrowych dla funkcji lubr
EAD iw
obrzędu, które biorą args nazwy pliku. Wszystkie muszą być przenośne\n
.Odpowiedzi:
Najwyższy czas, aby na to pytanie znalazła odpowiedź i chociaż w pewnym momencie intuicyjnie wymyśliłem, jak to zrobić właściwie w każdym przypadku, dopiero niedawno udało mi się dość konkretnie to zrozumieć dzięki tekstowi w standardzie . Jest tam powiedziane dość prosto - po prostu głupio przeoczyłem to wiele razy, tak myślę.
Odpowiednie fragmenty tekstu znajdują się pod nagłówkiem ...
Edycja poleceń w
sed
:Tekst argumentu składa się z jednego lub więcej wierszy. Każda osadzona
\n
ewline w tekście powinna być poprzedzona\
odwrotnym ukośnikiem. Pozostałe ukośniki w tekście zostaną usunięte, a następujący znak będzie traktowany dosłownie.Te
r
iw
czasowniki aktywnego, aw
flaga nas
rozkaz ma opcjonalny rplik (lub wplik ) parametru, oddzielone od polecenia czasownika litery lub flagi przez jeden lub więcej<blank>s
; implementacje mogą pozwolić na zerową separację jako rozszerzenie.Komenda czasowników innych niż
{
,a
,b
,c
,i
,r
,t
,w
,:
, i#
można następnie;
średnikiem, opcjonalnie<blank>s
, a innym czasownikiem poleceń. Jednakże, gdys
czasownik polecenia jest używany zw
flagą, następujące po nim polecenie w ten sposób daje niezdefiniowane wyniki....w...
Opcje: Można określić wiele
-e
i-f
opcje. Wszystkie polecenia należy dodać do skryptu w określonej kolejności, niezależnie od ich pochodzenia.-e
skrypt - Dodaj polecenia edycyjne określone przez argument opcja- skrypt na końcu skryptu poleceń edycyjnych. Argument opcja- skrypt powinien mieć takie same właściwości jak operand skryptu , opisany w sekcji OPERANDS .-f
plik_skryptu - Dodaj polecenia edycyjne w pliku plik_skryptu na końcu skryptu.I ostatni w ...
Operandy:
\n
ewline.Tak więc, jeśli weźmiesz to w całości, ma sens, że każde polecenie, po którym opcjonalnie występuje dowolny parametr bez predefiniowanego ogranicznika (w przeciwieństwie do
s d sub d repl d flag
na przykład), powinno rozgraniczać na\n
nieokreślonej ewline.Można argumentować, że
;
jest to predefiniowany ogranicznik, ale w takim przypadku użycie komendy;
for[aic]
wymagałoby włączenia osobnego analizatora składni do implementacji specjalnie dla tych trzech komend - oddzielnego, to znaczy[:brw]
na przykład od analizatora składni użytego . W przeciwnym razie implementacja musiałaby wymagać, aby w parametrze tekstowym był;
także znak odwrotnego ukośnika i od tego momentu staje się coraz bardziej skomplikowany.Jeśli I były pisanie
sed
którą chce się być zgodnych i skuteczny, to nie byłoby napisać taki osobny parser, spodziewam się - z wyjątkiem, że może[aic]
powinien gen błąd składni, jeśli nie od razu następuje\n
ewline. Ale jest to prosty problem z tokenizacją - przypadek ogranicznika końcowego jest na ogół bardziej problematyczny. Po prostu napisałbym to tak:...i...
... zachowałby się bardzo podobnie, ponieważ pierwszy utworzyłby i zapisał do pliku o nazwie:
... a drugi dołączałby blok tekstu do bieżącego wiersza na wyjściu, jak ...
... ponieważ oba będą dzielić ten sam kod parsowania dla parametru.
A jeśli chodzi o kwestię
{ ... }
i$!
problem - cóż, byłem tam daleko. Pojedyncze polecenie poprzedzone adresem nie jest funkcją, ale jest tylko poleceniem adresowanym. Prawie wszystkie polecenia - w tym{
definicja funkcji}
są określone do akceptacji/one/
lub/one/,/two/
adresów - z wyjątkiem definicji#
komentarza i:
etykiety . Adres może być numerem linii lub zwykłym wyrażeniem ekspresowym i można go zanegować!
. Więc wszystkie ...... może następować
;
więcej i więcej poleceń zgodnie ze standardem, ale jeśli dla jednego adresu potrzeba więcej poleceń, a adresu tego nie należy ponownie oceniać po wykonaniu każdego polecenia, należy użyć{
funkcji}
takiej jak:... gdzie
{
nie może nastąpić zamknięcie w tej samej linii}
i że zamknięcie}
nie może nastąpić inaczej niż na początku linii. Ale jeśli po poleceniu zawartym w przeciwnym razie nie powinna występować\n
ewline, to nie musi też występować w obrębie funkcji. Tak więc wszystkie powyższes///
wstawki - a nawet}
nawias zamykający , mogą być przenośnie poprzedzone;
średnikami i dalszymi poleceniami.\n
Wciąż mówię o ogranicznikach ewline, ale pytanie dotyczy zamiast tego-e
instrukcji xpression, wiem. Ale te dwa są tak naprawdę jednym i tym samym, a kluczową relacją jest to, że skrypt może być dosłownym argumentem wiersza polecenia lub plikiem z jednym z nich-[ef]
i że oba są interpretowane jako pliki tekstowe (które mają kończyć się na\n
ewline), ale żadna z nich nie musi kończyć się\n
ewline. Przez to mogę reasonbly (mam nadzieję) wywnioskować, że\0NUL
ograniczony argumentem implikuje kończącą\n
ewline, a wszystkie argumenty inwokacja dostać co najmniej) do\0NUL
ogranicznika tak, wówczas powinny działać prawidłowo.W rzeczywistości w każdym przypadku, z wyjątkiem jednego, w którym norma określa, że
\
nowa linia odwrotnego ukośnika powinna być wymagana, znalazłem przenośnie ...... równie dobrze pracować. I w każdym przypadku - znowu, w praktyce - gdzie
\n
wymagany jest ewline bez ucieczki ...... też dla mnie zadziałało. Jedynym wyjątkiem, o którym wspomniałem powyżej, jest ...
... co nie działa na żadnej implementacji w żadnym z moich testów. Jestem całkiem pewien, że sprowadza się to do wymogu dotyczącego pliku tekstowego i faktu, że
s///
pochodzi z separatora, więc nie ma powodu, aby jedna instrukcja obejmowała\0NUL
argumenty rozdzielane ograniczeniami.Podsumowując, oto krótki przegląd przenośnych sposobów pisania kilku rodzajów
sed
poleceń:Dla dowolnego z
[aic]
:...lub...
Dla każdego, w
[:rwtb]
którym parametr jest opcjonalny (dla wszystkich oprócz:
), ale ograniczający\n
ewline nie jest . Zauważ, że nigdy nie miałem powodu, aby wypróbować wiele parametrów etykiety linii , które byłyby używane[:tb]
, ale żew
riting /r
eading do wielu linii w parametrach pliku [rw] jest zwykle akceptowany bez pytania przezsed
s testowałem tak długo, jak osadzony\n
ewline jest poprzedzony\
ukośnikiem odwrotnym. Mimo to standard nie określa bezpośrednio, że parametry etykiety i pliku [rw] powinny być parsowane identycznie z tekstemparametrów i nie wspomina o\n
ewline dotyczących pierwszych dwóch, z wyjątkiem tego, że je wyznacza....lub...
... gdzie
<space>
powyższe jest opcjonalne dla[:tb]
.I ostatni...
...lub...
... gdzie każdy z wyżej wymienionych poleceń (z wyjątkiem
:
) akceptuje również co najmniej jeden adres , a które mogą być albo/
wyrażeniem regularnym/
lub numer linii i może być zanegowany z!
, ale jeśli więcej niż jedno polecenie jest konieczne dla pojedynczej oceny adresem następnie należy użyć nawiasów ograniczających{
kontekst funkcji}
. Funkcja może zawierać nawet wiele\n
poleceń rozdzielanych ewline, ale każda z nich musi być rozdzielana w nawiasach klamrowych, tak jak byłoby inaczej.I tak pisze się przenośne
sed
skrypty.źródło