2013-02-15 11 views
5

私の質問に対する答えは、SO上に存在する可能性がありますが、正直に見て、それを見つけることはできません。私が得た最も近いものはthis Q&Aでしたが、私のマシン(OSX 10.7.5、bashを使用)で結果を再現できませんでした。sedの16進コード - OSXで予期したとおりに動作しない

ここでは、本質的に縮小された問題です。sedは、\xnn(たとえば\x41A)を16進文字として解釈できません。六角以来、予想通り - ので、OSとその機能は私の進コードを理解して... B

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

結果 -

echo -e '\x41' 

Aでの結果:どのような私に特にナットを駆動するのはこれですそれを

しかし

echo A | sed 's/\x41/B/' 
を見た sed前にコードが Aに変換し、 A

結果 - 私はA

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

同上...で

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

結果で

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

結果のようなものを試してみましたB

を期待しているだろうA

しかし... B

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

結果???

私は完全に愚かですか?または、実際にはsedと奇妙な何かがありますか?明らかに範囲内の16進コードを解釈することはできますが、1文字として解釈することはできません。私は何が欠けていますか?

に注意してください - 私は上記はOSX上で、それはある方法を振る舞い、そしてどこでもsed文字列の単一進コードを挿入することを可能にする方法を、されている理由の両方が、説明の答えを探していますプラットフォーム。これは、s/コマンドの「検索」と「置換」の両方の部分を意味します。私が明らかに示しているので、[\ xnn- \ xnn]で1文字を検索することができます。それは私が探している答えではありません。

ありがとうございます!

答えて

8

「OSとその機能が何を理解しているか」という一般的な概念はありません。各プログラム、関数などは、メタキャラクタやエスケープなどの特定のセットを理解しています。そして、ちょうどsedは16進コード。しかし、(あなたがそれにせれば)bashはありませんので、あなたはそれがsed$''で呼び出す前に、それらを翻訳持つことができます。これはまた、あなたがしたいのであれば、sedに渡す前に、他のエスケープシーケンスを解釈すること

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

注意を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 

そして、あなたが解釈したい場合は六角は、一定ではなく、変数にエスケープ、文字列、あなたはかなりのsを使用する必要があります地獄のprintf組み込み:

$ hex=41 
$ echo A | sed "s/$(printf "\x$hex")/B/" 
B 
+0

ありがとうございます。 "sedが16進コードをしない"場合、どのように私の最後の例を説明しますか?* sedのような見た目は範囲式の16進数を理解しています... – Floris

+0

"私の最後の例をどう説明しますか?答え、以下... – Floris

+0

sed式の代替部分(2番目の部分)で16進符号化を使用する方法について詳しく説明していますか?私は試しました: 'echo -ne 'a \ x0db' | sed $ 's/\ x0d/\ x0a/g' |ヘックスダンプ-C'と 'echo -ne 'a \ x0db' | sed $ 's/\ x0d/\\ x0a/g' | hexダンプ-C'を無駄に使います。そうでなければ、これは私が探していたものでした。 – mpettis

3

@GordonDavissonは私に2つのことを試すためにインスピレーションを与えた...

まず第一に - 私が想定し、私は

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

の出力を誤って解釈された場合、私は突然、不思議に思いましたこれはsedが範囲内の\xnnコードを理解したことを意味しましたが、間違っていました。私は

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

をしようとしたときに私はそれ以上の範囲でA\x41)を含まないと思ったが、私は、Bの出力を得依然として。明らかに、sedは私の予想どおりに私の範囲を解釈していました。これはman 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!/'と表示されますが、sedの文字列に16進文字を挿入するという原則が確立されています。これが解決に役立たないのは、「エコーステートメントがsedでエスケープする必要がある文字を印刷する場合、どうなりますか?そして、私の基本的な質問にはまだ対処しません。 sed文字列。私はまだそれが可能であると思っています... sed( "古い"正規表現を使用すると主張していますが、-Eフラグは "拡張"式を使用することができますが、re_format詳細はmanページ、re_formatで参照されているre_syntaxのページです。これらの間では、実際に直接動作するはずの16進文字列を追加するように見えます...

私は信じているように、この情報を私の質問の「編集」ではなく「回答」として追加しましたは私の質問に答えるためにに始まります。

関連する問題