Czy ktoś może wyjaśnić, jak sed
działa to polecenie?
sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
sed
ten temat ! :)
Czy ktoś może wyjaśnić, jak sed
działa to polecenie?
sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
sed
ten temat ! :)
Odpowiedzi:
W sed polecenia zastępcze są zwykle zapisywane jako s/pattern/replacement/options
. Jednak nie jest konieczne użycie /
- możesz użyć innych znaków, jeśli jest to wygodne, więc może to być s@pattern@replacement@options
lub s:foo:bar:g
. s@+@ @g
jest jak s/+/ /g
- zamień wszystko +
spacjami. Podobnie s@%@\\x@g
zastępuje wszystkie %
z \x
(pojedynczy lewy ukośnik jest znakiem ucieczki w sed, więc trzeba dwa, aby uzyskać rzeczywistą backslash).
foo+%2Fbar
Stanie się taki ciąg foo \x2Fbar
. printf "%b"
rozwinie sekwencje specjalne z odwrotnym ukośnikiem, takie jak \x2F
(znak ASCII, którego wartość szesnastkowa to 2F, czyli /
), aby w końcu dać ci foo /bar
.
Polecenie, o które pytasz o dekodowanie +
es i %
sekwencji z adresów URL, to nie tylko sed
polecenie, to potok, który przetwarza dane wejściowe sed
, a następnie przesyła je do xargs
dalszego przetwarzania. Najpierw spójrzmy na sed
polecenie:
sed 's@+@ @g;s@%@\\x@g'
Możesz być bardziej przyzwyczajony do tego, że widzisz go /
raczej @
jako separator, co można łatwo zrobić bez komplikacji, ponieważ nie /
pojawia się w żadnym wzorcu wyszukiwania ani w tekście zastępczym. To polecenie jest równoważne:
sed 's/+/ /g;s/%/\\x/g'
Podobnie jak /
, @
jest idealnie dobrą postacią interpunkcyjną sed
.
W każdym wierszu danych wejściowych:
s@+@ @g
( s/+/ /g
) zastępuje ( s
) wystąpienia +
spacją. Wpływa to na wszystkie +
es na linii ( g
), nie tylko na pierwszą.
;
kończy działanie („polecenie”) i pozwala określić inną w tym samym „skrypcie”.
s@%@\\x@g
( s/%/\\x/g
) zastępuje ( s
) wystąpienia %
z \x
. Tak jak poprzednio, działa na wszystkich, a nie tylko na pierwszym wierszu ( g
).
W reprezentuje tylko jeden , ponieważ ma specjalne znaczenie . Jego szczególne znaczenie jest tak naprawdę, jak postać, której używasz, aby odebrać specjalne znaczenie kolejnej po niej postaci, która w innym przypadku miałaby specjalne znaczenie. Więc musi być jak .\\x
\\
\
\
sed
\\
Teraz spójrzmy na xargs
polecenie, którego celem jest uruchomienie printf
.
xargs
buduje linie poleceń. Jeśli uruchomisz , gdzie jest jedno lub więcej słów, zostanie uruchomione z dodatkowymi argumentami wiersza poleceń odczytanymi z jego danych wejściowych. W tym przypadku dane wejściowe to dane wyjściowe z powodu potoku ( ). Zwykle interpretuje dowolne białe znaki na swoim wejściu, co oznacza, że tekst przed i po nim stanowi osobne argumenty, ale opcja ta powoduje, że dzieli argumenty w przypadku wystąpienia znaku null .xargs command...
command...
xargs
command...
xargs
sed
|
xargs
-0
W zamierzonym użyciu polecenia znak null nie pojawi się i xargs
będzie działał printf %b
z jednym dodatkowym argumentem wiersza polecenia, wynikiem sed
polecenia. Tak więc, choć ogólnie nie jest to równoważne, w tym przypadku cały potok mógł zamiast tego zostać napisany w ten sposób przy użyciu podstawiania poleceń zamiast xargs
:
printf '%b\n' "$(sed 's/+/ /g;s/%/\\x/g')"
Jeśli chodzi o to, co printf
ma tu zostać zrobione, jak mówi muru, specyfikator %b
formatu zużywa i wypisuje argument (jak %s
), ale powoduje , że znaki odwrotnego ukośnika - takie jak sed
polecenie wygenerowane po lewej stronie potoku - zostało przetłumaczone w postacie, które reprezentują .
Załóżmy, że uruchamiam to polecenie i przekazuję http://foldoc.org/debugging%20by%20printf
jako dane wejściowe. Otrzymuję http://foldoc.org/debugging by printf
jako wynik, ponieważ %20
sekwencje są tłumaczone na spacje.
To piękno sed
, to stosuje swoje paradygmaty do siebie ... Po wydaniu polecenia (takie jak s
albo tr
albo nic), następny znak jest uważany za separator.
Powinieneś mądrze wybrać, aby uniknąć ingerencji w powłokę i samą komendę oraz zachować czytelność, ale napisanie czegoś tak okropnego jak:
echo 'arrival' | sed srarbrg
... i uzyskaj brrivbl
w rezultacie to, czego oczekujesz. Możesz się dobrze bawić, czyniąc go naprawdę tajemniczym, na przykład:
echo 'arrival' | sed s\fa\fb\fg # \f is form feed, chr(12)
Powszechnym zastosowaniem jest użycie ukośnika jako ogranicznika, ale gdy twoje wyrażenie zawiera ogranicznik, łatwiej jest uchwycić zamiar. Ogranicznikiem może być dowolny element z zakresu ASCII8 (ograniczniki wielobajtowe, takie jak £
wywołać błąd).
Pamiętaj tylko, że celem jest uczynienie rzeczy łatwiejszymi, a nie bardziej tajemniczymi.
sed "snack is an apple or something" <<< "I sed your snack is an apple or something"
sed
poleceń jako łamigłówek, jaki to jest naukowy?