多数の@記号を含むこの「sed」置換コマンドはどのように機能しますか?


8

誰でもこのsedコマンドがどのように機能するか説明できますか?

sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"

3
これを行う通常の方法はスラッシュを使用することですが、何かを検索してスラッシュで置き換えると、面倒になる場合があります。ここではそうではないので、完全に問題なくても、将来のメンテナを混乱させることになります。
–ThorbjørnRavn Andersen 2017

2
…そして、彼らにsedこの方法について何か新しいことを学ぶように導きます!:)
デザート

回答:


15

sedでは、代替コマンドは通常として記述されs/pattern/replacement/optionsます。ただし、必ずしも使用する必要はありません。/便利であれば他の文字を使用できるので、s@pattern@replacement@optionsまたはでもかまいませんs:foo:bar:gs@+@ @gのようですs/+/ /g-すべて+をスペースに置き換えます。同様にs@%@\\x@g、すべて%を次のものに置き換えます\x(単一のバックスラッシュはsedのエスケープ文字なので、実際のバックスラッシュを取得するには2つ必要です)。

のような文字列foo+%2Fbarはになりfoo \x2Fbarます。(16進値が2FであるASCII文字)のprintf "%b"ようなバックスラッシュエスケープシーケンスを拡張して、最終的にを提供します。\x2F/foo /bar


2
簡単に言うと、URL-> filenameデコーダーです。
–ThorbjørnRavn Andersen 2017

10

URLから+esと%シーケンスをデコードするために求めているsedコマンドは、単なるコマンドではなく、を使用して入力を処理し、さらに処理するためにそれをパイプするパイプラインです。最初にコマンドを見てみましょう:sedxargssed

sed 's@+@ @g;s@%@\\x@g'

セパレータとしてで/はなく、@を使って表示する方が慣れているかもしれません。これ/は、検索パターンにも置換テキストにも表示されないため、ここでは簡単に行うことができます。このコマンドは同等です。

sed 's/+/ /g;s/%/\\x/g'

のように/@は完全に適切な句読文字ですsed

入力の各行で:

  1. s@+@ @gs/+/ /g)は(s)の出現箇所を+スペースで置き換えます。これは、最初のものだけでなく+、行のすべてのes(g)に影響します。

  2. ; アクション(「コマンド」)を終了し、同じ「スクリプト」で別のアクションを指定できるようにします。

  3. s@%@\\x@gs/%/\\x/g)代替(s)の発生%\x。前と同様に、各行の最初の行だけではなく、すべてに対して機能します(g)。

    でただ一つを表すために特別な意味を持っています。その特別な意味は、実際には、その後に続く別の文字の特別な意味を持つ別の文字の特別な意味を取り除くために使用する文字と同じです。したがって、としてエスケープする必要があります。\\x\\\\sed\\


次に、xargsを実行することを目的としたコマンドを見てみましょうprintf

xargsコマンドラインを構築します。あなたが実行している場合場合は、一つ以上の単語があり、実行し、追加して、コマンドライン引数は、その入力から読み込みます。この場合、パイプ()があるため、への入力はの出力です。通常、入力内の空白を解釈して、前後のテキストが個別の引数を構成することを意味しますが、このオプションを使用すると、ヌル文字の出現時に引数が分割されます。xargs command...command...xargscommand...xargssed|xargs-0

コマンドの使用目的では、null文字は表示されず、1つの追加のコマンドライン引数であるコマンドの出力でxargs実行さprintf %bsedます。したがって、一般的には同等ではありませんが、この場合、パイプライン全体が次のようにコマンド置換を使用してこのように記述されている可能性がありxargsます。

printf '%b\n' "$(sed 's/+/ /g;s/%/\\x/g')"

ここで何printfをするつもりかについては、muru%bフォーマット指定子%sが(のように)引数を消費して出力しますが、バックスラッシュエスケープを引き起こします- sedパイプの左側のコマンドが生成するように作成されたような- 変換されるそれらが表す文字に

そのコマンドを実行しhttp://foldoc.org/debugging%20by%20printf、入力として渡すとします。シーケンスはスペースに変換されるhttp://foldoc.org/debugging by printfため、出力として取得%20します。


3

それがの優れた点でありsed、そのパラダイムをそれ自体に適用します...コマンド(sまたはtrorなしなど)の後、次の文字は区切り文字と見なされます。

シェルやコマンド自体との干渉を避け、読みやすくするために賢明な選択をする必要がありますが、次のような恐ろしいものを書くことは完全に有効です。

echo 'arrival' | sed srarbrg

...そしてbrrivbl結果として得られます。これはあなたが期待することです。次のように、それを本当に不可解なものにして楽しむことができます。

echo 'arrival' | sed s\fa\fb\fg   # \f is form feed, chr(12)

スラッシュを区切り文字として使用するのが一般的な使用法ですが、式に区切り文字が含まれていると、意図が何であるかを簡単に把握できます。区切り文字には、ASCII8の範囲の任意の文字を使用できます(£エラーを引き起こすなどのマルチバイト区切り文字)。

目標は、物事をよりわかりやすくすることであり、よりわかりやすくすることではありません。


それは何も有効ではありませんけれども不可解なアイデアを実行して、これは、有効なsedコマンドである:sed "snack is an apple or something" <<< "I sed your snack is an apple or something"
wjandrea

いいね!はい、sedコマンドを頭の体操として使用することもできます。
Marabiloso 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.