Czy ktoś może wyjaśnić, jak seddziała to polecenie?
sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
sedten temat ! :)
Czy ktoś może wyjaśnić, jak seddziała to polecenie?
sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
sedten 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@optionslub s:foo:bar:g. s@+@ @gjest jak s/+/ /g- zamień wszystko +spacjami. Podobnie s@%@\\x@gzastępuje wszystkie %z \x(pojedynczy lewy ukośnik jest znakiem ucieczki w sed, więc trzeba dwa, aby uzyskać rzeczywistą backslash).
foo+%2FbarStanie 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 sedpolecenie, to potok, który przetwarza dane wejściowe sed, a następnie przesyła je do xargsdalszego przetwarzania. Najpierw spójrzmy na sedpolecenie:
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 xargspolecenie, którego celem jest uruchomienie printf.
xargsbuduje 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...xargscommand...xargssed|xargs-0
W zamierzonym użyciu polecenia znak null nie pojawi się i xargsbędzie działał printf %bz jednym dodatkowym argumentem wiersza polecenia, wynikiem sedpolecenia. 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 printfma tu zostać zrobione, jak mówi muru, specyfikator %bformatu zużywa i wypisuje argument (jak %s), ale powoduje , że znaki odwrotnego ukośnika - takie jak sedpolecenie 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%20printfjako dane wejściowe. Otrzymuję http://foldoc.org/debugging by printfjako wynik, ponieważ %20sekwencje są tłumaczone na spacje.
To piękno sed, to stosuje swoje paradygmaty do siebie ... Po wydaniu polecenia (takie jak salbo tralbo 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 brrivblw 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"
sedpoleceń jako łamigłówek, jaki to jest naukowy?