web-dev-qa-db-ja.com

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

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

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

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

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

15
muru

RLから+esおよび%シーケンスをデコードするように求めているコマンド は、単なるsedコマンドではなく、 sed で入力を処理する pipeline です=、さらに処理するために xargs にパイプします。最初にsedコマンドを見てみましょう:

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

/は検索パターンにも置換テキストにも表示されないため、@を区切り文字としてではなく/を使用して表示することに慣れている場合があります。このコマンドは同等です:

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

/と同様に、@sedの句読点として最適です。

入力の各行で:

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

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

  3. s@%@\\x@gs/%/\\x/g)は、%の(s)オカレンスを\xに置き換えます。前と同様に、各行の最初(g)ではなく、すべてに作用します。

    \\xでは、\\sedに対して特別な意味を持つため、\は1つの\を表します。その特別な意味は、実際には、そうでなければ特別な意味を持つ別のキャラクターの特別な意味を取り去るために使用するキャラクターとしてのものです。したがって、\\としてエスケープする必要があります。


では、 xargs を実行することを目的とするprintfコマンドを見てみましょう。

xargsはコマンドラインを構築します。 xargs command...を実行する場合、command...は1つ以上のWordで、xargsは追加の コマンドライン引数付きでcommand...を実行します その入力から読み取ります。この場合、パイプ(|)により、xargsへの入力はsedの出力になります。通常、xargsは入力の空白を解釈して、前後のテキストが個別の引数を構成することを意味しますが、-0オプションは、代わりに null character の出現時に引数を分割します。

コマンドの使用目的では、ヌル文字は表示されずxargsは、コマンドライン引数を1つだけ追加してsedコマンドの出力でprintf %bを実行します。したがって、一般的には同等ではありませんが、この場合、代わりにxargsの代わりに command substitution を使用して、パイプライン全体を次のように記述できます。

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

printfがここで行うことを意図しているのは、 as muru says%b形式指定子は引数を消費して出力します(%sなど) )しかし、バックスラッシュエスケープが発生します-パイプの左側にあるsedコマンドが生成するように記述された種類の それらが表す文字に変換される です。

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

10
Eliah Kagan

それはsedの美しさであり、そのパラダイムをそれ自体に適用します...コマンド(sまたはtrまたはゼロなど)の後、次の文字はセパレーターと見なされます。

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

echo 'arrival' | sed srarbrg

...そして、結果としてbrrivblを取得します。次のように、本当に謎めいたものにすることができます。

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

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

目標は、物事をよりわかりやすくすることであり、よりわかりにくいものにすることです。

3
Marabiloso