8

私の質問への答えは SO にあるかもしれませんが、正直なところ、一生懸命探しても見つかりません。最も近いのはこの Q&Aでしたが、自分のマシン (OSX 10.7.5、 を使用) で結果を再現できませんでしたbash

これが問題の本質です: を16進文字としてsed解釈でき\xnnません。特に私を夢中にさせているのはこれです:\x41A

echo -e '\x41' 

その結果A-OSとその機能は私の16進コードを理解します...

echo -e '\x41' | sed 's/A/B/'

結果はB- 16 進コードが表示されるA前に変換されsedたため、予想どおり

しかし

echo A | sed 's/\x41/B/'

結果A- 私は期待していたでしょうB

私は次のようなことを試しました

echo A | LANG='C' sed 's/\x41/B/'

結果はA

echo A | LANG='' sed 's/\x41/B/'

同上...

echo A | sed 's/[\x41]/B/'

結果はA

しかし...

echo A | sed 's/[\x41-\x41]/B/'

結果はB???

私は完全に愚かですか?それとも本当に何か変sedですか?どうやら範囲内の16進コードを解釈できますが、1文字として解釈することはできません。私は何が欠けていますか?

注意してください - OSX プラットフォームで、上記の動作がなぜそうなのかを説明する回答と、文字列内の任意の場所に単一の 16 進コードを挿入できるようにする方法の両方を説明する回答を探しています。これは、コマンドの「検索」部分と「置換」部分の両方を意味します。[\xnn-\xnn] を使用して単一の文字を検索できることを明らかに示したので、それは私が探している答えではありません。seds/

前もって感謝します!

4

2 に答える 2

12

「OSとその関数が理解する」という一般的な概念はありません。各プログラム、関数などは、独自のメタ文字のセット、エスケープなどを理解します。そして、sed16進コードを実行しないことが起こります。しかし、bashは(あなたがそれを要求した場合)そうするので、あなたはそれを呼び出す前にそれらを翻訳させることができsedます$''

$ echo A | sed $'s/\x41/B/'
B

これは、に渡す前に他のエスケープシーケンスも解釈することに注意してくださいsed。したがって、エスケープをに渡したい場合は、sedそれらをダブルエスケープするか、引用モードを切り替えて、関連する部分のみが含まれるようにする必要があります$''

$ echo A | sed $'s/\\(\x41\\)/B\\1/' # double-escapes for sed's escape sequences
BA
$ echo A | sed 's/\('$'\x41''\)/B\1/' # equivalent with different quote modes
BA
$ echo A | sed 's/\(A\)/B\1/' # simplest equivalent version
BA

また、定数ではなく変数の文字列で16進エスケープを解釈する場合は、シェルのprintf組み込みを使用する必要があります。

$ hex=41
$ echo A | sed "s/$(printf "\x$hex")/B/"
B
于 2013-02-15T07:20:12.033 に答える
6

@GordonDavissonは、さらに2つのことを試すインスピレーションを与えてくれました...

まず最初に - の出力を誤解しているのではないかと突然思いました

echo A | sed 's/[\x41-\x41]/B/'

sedこれは が範囲内のコードを理解したという意味だと\xnn思っていましたが、それは間違いでした。私が試したとき

echo A | sed 's/[\x40-\x40]/B/'

範囲に( )を含めていないと思っていましたが、まだの出力が得られました。明らかに、私の範囲を予想とは異なる方法で解釈していました。これは、ページをより注意深く見ることで解決されました。それは言うBA\x41sedman re_format

[...] `\' を含む他のすべての特殊文字は、ブラケット式内で特別な意味を失います。

しかし、私はひらめきを得ました:echo -eひもを広げることができれば、それを使って私が望むひもを養うことができるかもしれませんsed...

echo "This?" | sed `echo -e 's/\x54\x68\x69\x73\x3F/\x59\x65\x73\x21/'`

プロデュースYes!

echo "That?" | sed `echo -e 's/\x54\x68\x69\x73\x3F/\x59\x65\x73\x21/'`

プロデュースThat?

もちろん、この場合、\xnn文字は単純な ASCII を表します。文字列をデコードすると、文字列に's/This?/Yes!/'16 進文字を挿入するという原則が確立されsedます。これが片付けに役立たない唯一のことは、「あなたのechoステートメントがエスケープする必要がある文字を出力するとどうなるsedかですsed. 私はまだそれが可能であると思っています...ドキュメントを読んだ後はなおさらですsed(これは「古い」正規表現を使用すると主張していますが、 -E フラグは「拡張された」表現を使用できるようにし、ユーザーをre_formatマニュアルページに誘導します詳細については、およびre_syntaxによって参照されるページre_format. これらの間で、16進文字列を追加すると直接機能するように見えます...

この情報は、私の質問に「編集」ではなく「回答」として追加しました。これは、私の質問に答え始めると信じているためです...コメントを楽しみにしています!

于 2013-02-15T13:46:46.097 に答える