
私は特定のコマンドでバックスラッシュがどのように使用されるかをよりよく理解しようとしました。特殊文字(例:)をエスケープするために使用されることは理解されていますecho 'that'\''s no moon'
が、他のコマンドの出力は少し混乱しています。たとえば、
rpm-qa rpmname\*
grep '\s/tmp' /etc/fstab
誰かが私がこの問題を解決するのを助けることができますか?また、あなたが知っている他の用途についても気になります。ありがとうございます!
答え1
バックスラッシュは、「次の文字に特別な意味を与えるのではなく、それ自体を示すようにする」という意味でよく使われます。私たちはバックスラッシュです。引用符次のキャラクター。この意味は、シェル構文を含む多くのプログラミング言語に存在します。たとえば、でrpm-qa rpmname\*
バックスラッシュを使用すると、文字はコマンド引数*
として渡されます。rpm-qa
代わりに、現在のディレクトリで.にrpm-qa rpmname*
置き換えてください。 (一致するファイルがない場合、bashは表示されません。デフォルトでは、zshは一致するファイルがないと文句を言います。)rpmname*
rpmname
rpmname*
シェルは、文字を文字通り解釈する別の方法、すなわち特別な方法で解釈されるのではなく、それ自体を表現する方法を提供します。これは文字シーケンス全体の特別な意味を排除する引用です。引用符には2種類あります。一重引用符は'
各文字が次の一重引用符までそれ自体を表すようにしますが、二重引用符は"
いくつかの文字(、、、および)に対して"
特別な$
意味を持ちます。で、コマンドは(特定の場合に特別な意味を持つ文字ではなくリテラル文字列で書かれています)を連結した引数を受け取ります(バックスラッシュの一重引用符は特別な意味を取り消すため、一重引用符に展開されます)。文字)と(スペースは引用符内にあるため、特別な意味を失います。パラメータを区別せずにパラメータの一部です)。\
`
echo 'that'\''s no moon'
echo
that
'
s no moon
シェルでバックスラッシュが特別な意味を持つ場合は、通常、次の文字を引用します。しかし:
- 一重引用符内では、バックスラッシュは特に意味がありません。
- 二重引用符内で、バックスラッシュは次の文字が1つの場合にのみ引用符を付けます
"$\`
。それ以外の場合、バックスラッシュと次の文字は文字通り"\a"
2文字に解決されます\a
。 - ドル一重引用符リテラルでは、バックスラッシュは次のような異なる意味を持ちます。氏。バックスラッシュの後に8進数または特定の文字が続く場合は、文字を入力する代替方法を提供します。これは印刷できない文字に役立ちます。たとえば、バックスラッシュ+nの小文字
\n
Nですが、改行文字です。"\n"
$'\n'
では、grep '\s/tmp' /etc/fstab
一重引用符はgrep
パラメータを受け取ります\s/tmp
。この主張は正規表現。正規表現にはさまざまな構文バリアントがありますが、ほとんどは次の2つの基準のいずれかに基づいています。POSIX 基本正規表現 (BRE) および拡張正規表現 (ERE)。 EREは、バックスラッシュの後に文字または数字以外の文字を使用して、次の文字を参照する広範な規則に従います。しかし、歴史的な理由から、BREではバックスラッシュが特別なケースではなく、次の文字を特別にすることがあります。この場合、\s
BRE および ERE で使用できる基本正規表現構文の GNU grep 拡張は空白文字を表します。したがって、前にスペースやタブがある行が一覧表示されますgrep '\s/tmp' /etc/fstab
。/etc/fstab
/tmp
答え2
私はあなたがbashまたは同様のものを使用していると仮定します。
まず、bashが入力を評価する方法を理解する必要があります。 Bashでは、多くの特殊文字を使用できます。たとえば、それらのいくつかは次のとおりです。* ; ~ $
入力中、bashは置き換える必要があるすべての文字を置き換えようとします。たとえば、$
記号で始まる変数です。*
現在のディレクトリに存在するすべてのファイル/ディレクトリに置き換えられます(OKを使用)pwd
。
交換ステップが完了すると、bash は最終的に指定したfork()
プログラムを実行します。
\
指定された特殊文字を無視するようにbashに指示します。\*
答え3
そうですね。バックスラッシュを使用して文字をエスケープしたり、その文字が特別な意味を持ち、文字をそのまま使用したいという一般的な慣例があります。
# echo 'It\'s a string!'
上記の例では、アポストロフィはリテラル文字列を区切るために使用されていますが、文字列にはアポストロフィが必要なのでエスケープする必要があります。
他の場合はその逆です。特別な意味を持つために「一般」文字が必要な場合です。
# grep '\s/tmp' /etc/fstab
上記の例では、バックスラッシュはgrepにs
特別な意味を持ち、リテラルではないことを示していますs
(正規表現スペース:スペース、タブ、改行、キャリッジリターン、垂直タブ)。
つまり、文字に2つの意味があるときにエスケープして2番目の意味を持つようになります。
編集する:
最初の例は次のとおりです。
rpm-qa rpmname\*
これには特別な意味(「rpmname」で始まるすべて)がありますが、シェルがそれを拡張しないようにするには、コマンドがリテラルを取得してそれに応じて処理できるように*
エスケープする必要があります。rpm
*
これにより、文字列が複数回解釈され、文字列が複数のコマンドによって渡されると、実際に問題が発生する可能性があります。
答え4
\
特殊文字をエスケープして正規表現をトリガーするために使用されます。
あなたのrpm
コマンドはescaping中です*
。この場合、エスケープしないのと同じように動作します。 RPMはこれが*
間違ったパッケージ文字であることを知っているので、エスケープしてもそれを解釈します。エスケープされた特殊文字は、英数字ではなくファイル名などの状況でより一般的に使用されます。
「foo-biz-bar」という名前のファイルと「foo*bar」という名前のファイルがあり、「foo*bar」だけを見たいとしましょう。以下の最初の結果は、BLOBワイルドカードがエスケープされていないためです*
。
$ ls foo*bar
foo*bar foo-biz-bar
$ ls foo\*bar
foo*baz
\s
例にあるのは、grep
タブとスペースの「すべてのスペース」を意味する正規表現です。
追加読書
オンラインで正規表現の完全なリストを取得するのは難しいですが、始めることはできます。ここ。
私に多くの助けを与えた本は「Unix Shells byの例」です。sed
、grep
およびの広範な使用法もawk
カバーしています。