私は、入力として正規表現を必要とするLinuxプログラムprogram
を自分で作成しました。
bash
シェルでプログラムを呼び出し、その正規表現をコマンドライン引数としてプログラムに渡します(他のコマンドライン引数もあります)。典型的な正規表現は次のようになります
[abc]\_[x|y]
残念ながら、文字[
、]
、|
はbash
の特殊文字です。したがって、
program [abc]\_[x|y] anotheragument
動作しません。なんらかのエスケープ文字や引用符などを使用して式を渡す方法はありますか?
(program "[abc]\_[x|y] anotheragument"
の呼び出しも、2つの引数を1つとして解釈するため、機能しません。)
単一引用符を使用します。一重引用符は、どの文字も解釈されないようにします。
$ printf %s 'spaces are not interpreted away
neither are new lines
nor variable names $TESTING
nor square brackets [TESTING]
nor pipe characters or redirection symbols | > <
nor the semicolon ;
nor backslashes \a \b \c \\
the only thing that does not work is the single quote itself
'
単一引用符を埋め込む必要がある場合、2つの解決策があります。
$ printf '%s\n' '[ Don'"'"'t worry, be happy! ]'
[ Don't worry, be happy! ]
$ printf '%s\n' '[ Don'\''t worry, be happy! ]'
[ Don't worry, be happy! ]
man bash
エスケープ文字、一重引用符、二重引用符の3つの引用メカニズムがあります。
引用符で囲まれていないバックスラッシュ(\)は、エスケープ文字です。 <newline>を除いて、次の文字のリテラル値を保持します。 \ <newline>ペアが表示され、バックスラッシュ自体が引用されていない場合、\ <newline>は行の継続として扱われます(つまり、入力ストリームであり、事実上無視されます)。
文字を単一引用符で囲むと、引用符内の各文字のリテラル値が保持されます。バックスラッシュが前に付いている場合でも、単一引用符の間で単一引用符が発生しない場合があります。
文字を二重引用符で囲むと、$、`、\、および例外として、引用符内のすべての文字のリテラル値が保持されます。履歴の拡張が有効です!。文字$および`は、二重引用符内で特別な意味を保持します。バックスラッシュは、次のいずれかの文字が続く場合にのみ特別な意味を保持します:$、`、"、\ =、または<newline>。二重引用符は、バックスラッシュを前に付けることにより、二重引用符で囲むことができます。有効にすると、!が出現しない限り、履歴の展開が実行されます二重引用符は円記号を使用してエスケープされます!の前の円記号は削除されません。
特別なパラメーター*および@は、二重引用符で囲まれた場合に特別な意味を持ちます(以下の[〜#〜] parameters [〜#〜]を参照)。
形の言葉 $ 'ストリング」 特別に扱われます。 Wordはstringに展開され、バックスラッシュでエスケープされた文字はANSI C標準で指定されているとおりに置き換えられます。バックスラッシュエスケープシーケンスが存在する場合は、次のようにデコードされます。
\ a 警告(ベル) \ b バックスペース \ e\ E エスケープ文字 \ f フォームフィード \ n 改行 \ r キャリッジリターン \ t 水平タブ \ v 垂直タブ \\ バックスラッシュ \ ' 一重引用符 「」 二重引用符 \nnn 値が8進値である8ビット文字 nnn (1から3桁) \バツHH 値が16進値である8ビット文字 HH (1桁または2桁の16進数) \ uHHHH 値が のUnicode(ISO/IEC 10646)文字、16進値 HHHH (1から4桁の16進数) \ UHHHHHHHH 値が のUnicode(ISO/IEC 10646)文字。16進値 HHHHHHHH (1から8桁の16進数) \ cバツ コントロール-バツ キャラクター展開された結果は、ドル記号が存在しないかのように、単一引用符で囲まれています。
ドル記号が前に付いた二重引用符で囲まれた文字列($ "ストリング」)は、現在のロケールに従って文字列を翻訳します。現在のロケールが[〜#〜] c [〜#〜]または[〜#〜] posix [〜#〜]の場合、ドル記号は無視されます。文字列が翻訳および置換される場合、置換は二重引用符で囲まれます。
バックスラッシュ(\
)特殊文字の前で、次のようにエスケープします。
john @ awesome:〜#echo \& &
正規表現としては役に立たないかもしれませんが、一部の文字シーケンスはBash変数名として解釈される場合があります。これが発生するのを防ぎ、展開されないようにするには、二重引用符の代わりに単一引用符を使用します。
program '[abc]_[x|y]' anotherargument
各引数を個別に引用(引用が必要な場合)するため、独立した引数として解釈されます。場合によっては配列を使用することもできます。
param_array=('[abc]_[x|y]' anotherargument) # create an array
param_array+=(yetanother) # append another element to the array
program "${param_array[@]}" # use the array elements as arguments to program
program "[abc]_[x|y]"
program "[abc]_[x|y]" anotherargument
パターンはどこから来たのですか?それは修正されたものですか、それともユーザーからのものですか?ローカルシステムでスクリプトを呼び出しているのはユーザーですか、それともリモートの誰かですか。
引用符を使用してデータをラップし、シェルがデータを解釈しないようにします。 2つのオプションがあります。
_$
_は正規表現(行末/バッファー)で有効な文字であるため、変数に格納しない限り、単一引用符を使用して正規表現を保持することをお勧めします。信頼できない人から任意のデータを取得する場合は、_'
_を_'"'"'
_に置き換えてから、単一引用符で囲む必要があります。
_[abc]_[x|y]
_は、x
またはy
に一致するように見えますが、実際には、3つの文字_xy|
_のいずれかに一致します。角括弧は、範囲の場合は_-
_内の文字に一致し、否定の場合は先頭に_^
_が一致します。したがって、[abc]_(x|y)
はあなたが意図したものである可能性があり、括弧はシェルに特有の文字です。角括弧はシェルにとって特別なnotです。二重角括弧_[[ ... ]]
_は特別です。
それらをエスケープするとうまくいくはずです:
programm \[abc\]_\[x\|y\]