Хтось може пояснити, як sedпрацює ця команда?
sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
sedцей спосіб! :)
Хтось може пояснити, як sedпрацює ця команда?
sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
sedцей спосіб! :)
Відповіді:
У sed команди, що замінюють, зазвичай записуються як s/pattern/replacement/options. Однак використовувати це не обов’язково /- ви можете використовувати інші символи, якщо це зручно, так це могло бути s@pattern@replacement@optionsабо s:foo:bar:g. s@+@ @gце як s/+/ /g- замінити все +пробілами. Аналогічно s@%@\\x@gзамінює все %на \x(один зворотний косий рядок є символом втечі в sed, тому вам потрібно два, щоб отримати фактичний зворотний кут).
Тоді такий рядок foo+%2Fbarстане foo \x2Fbar. printf "%b"розширить схожі послідовності на зразок \x2F(символ ASCII, шістнадцяткове значення якого становить 2F, тобто /), нарешті, дасть вам foo /bar.
Команда, про яку ви просите розшифрувати +es та %послідовності з URL-адрес, - це не просто sedкоманда, це конвеєр, який обробляє вхід sed, а потім передає його xargsдля подальшої обробки. Спочатку давайте подивимось на sedкоманду:
sed 's@+@ @g;s@%@\\x@g'
Ви можете бути більш звикли бачити це /не @як роздільник, що легко можна було б зробити тут без ускладнень, оскільки не /з'являється в жодному з шаблонів пошуку, ані в жодному із текстів заміни. Ця команда рівнозначна:
sed 's/+/ /g;s/%/\\x/g'
Мовляв /, @ідеально хороший розділовий символ для sed.
У кожному рядку введення:
s@+@ @g( s/+/ /g) замінює ( s) входження +з пробілом. Це впливає на всі +es у рядку ( g), а не лише на першому.
; завершує дію ("команда") і дозволяє вказати ще одну в тому ж "скрипті".
s@%@\\x@g( s/%/\\x/g) замінники ( s) виникнення %с \x. Як і раніше, він діє на всі, а не лише на перший з кожного рядка ( g).
В представляє тільки один , тому що має особливе значення для . Його особливий сенс насправді як персонаж, який ви використовуєте, щоб забрати особливе значення іншого персонажа, що приходить після нього, яке б інакше мало особливе значення. Тому його треба уникати як .\\x\\\\sed\\
Тепер розглянемо xargsкоманду, мета якої - запустити printf.
xargsбудує командні рядки. Якщо ви запустите , де є одне або декілька слів, виконуються з додатковими аргументами командного рядка, прочитаними з його введення. У цьому випадку вхід до - це вихід , через трубу ( ). Зазвичай інтерпретує будь-який пробіл у своєму введенні, щоб означати, що текст до та після нього становить окремі аргументи, але параметр змушує його розділяти аргументи на місцях появи нульового символу .xargs command...command...xargscommand...xargssed|xargs-0
При використанні команди, призначене для використання, нульовий символ не з’явиться і xargsбуде працювати printf %bлише з одним додатковим аргументом командного рядка, висновком sedкоманди. Таким чином, хоч і не є рівнозначним загалом, у цьому випадку весь конвеєр може бути написаний таким чином, використовуючи заміну команди замість xargs:
printf '%b\n' "$(sed 's/+/ /g;s/%/\\x/g')"
Що ж стосується того, що printfпередбачається зробити тут, в Мурі говорить про %bформаті специфікатор споживає і друкує аргумент (наприклад %s) , але викликає зворотний слеш - від сортування по sedкоманді на лівій стороні труби була написано для створення - бути переведено в символи, які вони представляють .
Припустимо, я запускаю цю команду і передаю http://foldoc.org/debugging%20by%20printfяк вхід. Я отримую http://foldoc.org/debugging by printfяк вихід, тому що %20послідовності перекладаються на пробіли.
Це краса sed, вона застосовує свої парадигми до себе ... Після команди (наприклад, sчи , trабо нічого), то наступний символ вважається роздільником.
Вам слід вибрати розумно, щоб уникнути втручання в оболонку та саму команду, і тримати річ читабельною, але цілком справедливо написати щось таке жахливе, як:
echo 'arrival' | sed srarbrg
... і отримуйте brrivblрезультат, якого ви очікуєте. Ви можете розважитися, зробивши це по-справжньому виразним, як-от у:
echo 'arrival' | sed s\fa\fb\fg # \f is form feed, chr(12)
Загальне використання - використовувати косу рису в якості роздільника, але коли ваш вираз містить роздільник, це полегшує розуміння того, що є наміром. Вашим роздільником може бути що завгодно в діапазоні ASCII8 (багатобайтові роздільники, такі як £спровокувати помилку).
Просто пам’ятайте, мета - зробити речі простішими, а не більш виразними.
sed "snack is an apple or something" <<< "I sed your snack is an apple or something"
sedкоманди і як тизери для мозку, наскільки вигідний це?