bashでは、感嘆符をエスケープするにはどうすればよいですか?


183

みたいなことをしたいbzr commit -m "It works!"。することで感嘆符をエスケープすることができますbzr commit -m "It works\!"。ただし、コミットメッセージにはバックスラッシュが含まれます。バックスラッシュを無視しながら、感嘆符をエスケープするにはどうすればよいですか?


1
やってbzr commit -m "It works"!も、作品を。
kba

1
前に書いたように、入力したコマンドは実際に動作します:)bzr commit -m "It works!"
h4unt3r 14


1
受け入れられた答えはあなたのコミットの問題に対する良い回避策ですが、実際の問題に対する答えではないと感じています:Bash history expansion。デニスの答えを受け入れることを検討してください?
アルジャン

回答:


153

コミットメッセージの変数を展開するためにbashに依存しないため、代わりに単一引用符を使用できます。単一引用符で囲まれた文字列は、bashによって展開されません。

bzr commit -m 'This does work!' 

24
質問は「どうすれば感嘆符をエスケープできますか?」「感嘆符を展開しない方法」ではありません 私はこれが有効だとは思わない。これが機能しない場合があります(同じコマンドラインでアポストロフィと感嘆符を渡す場合など)。以下の答えは、多くの人々が必要とすることを行うためにはるかにうまく機能します。
-Jann

7
@Jann:あなたはこれについて100%正しいですが、問題はここにあると思いますスーパーユーザーに関する質問が非常に多いものです:私たちはその質問に答えるか、特定の問題を解決するのを助けますか?両方の方法が役立つと思いますが、これは特定の問題に関するヘルプを探していました。
ベンジャミンバニエ

touché!これは特定の問題でした。私は自分の質問に対する答えを多くの状況で使えるようにしたいだけです。pS:これに言及した理由は、アポストロフィと感嘆符の両方をperlプログラムに渡す必要があり、以下の解決策が必要だったからです。:)
ヤン

私はベンジャミンとジャンの両方に同意しますが、下票を与えました。質問のタイトルは検索エンジンによって索引付けされており、それが私がここに来た方法であり、おそらくほとんどのユーザーがここに来ます。だからこそ、実際の質問がその背後にある問題を反映していることが重要だと思います。他のフォーラムでは、人々は自分が何を探しているのかを正確に尋ねることを(ほぼ強制的に)勧められています。不十分に表明された質問に答えることは、ずさんなことをサポートし、それがここでの私のダウン投票の正確な理由です。妥協/解決策として、私の提案は、実際の問題を反映するように見出しを適応させることです。
クリストフ

153

二重引用符と感嘆符が必要な場合の別の方法を次に示します。

echo "It's broken"'!'

!が行末になくても機能します。

例えば:

echo "hello there"'!'" and goodbye"

ボーナス:同様の手法を使用して、ShまたはBashのテキストを(sedを使用して)エスケープできます。この回答の最初のオプションを参照してください。さらに、bash-completionインストール済みの場合は、おそらくそのquote()機能が既に使用可能になっています。


4
いいヒント、JWD。bash文字列は、それらの間の空白を省略するだけで連結できるとは思いませんでした。
アランH.

実際、エクスクラメーションマークが文字列の末尾にある場合は、クリアである場合はecho "Happy birthday!"期待どおりに動作します。そうでない場合はバックスラッシュでエスケープできますが、バックスラッシュも出力されます。
h4unt3r 14

@ h4unt3r:奇妙な、それは私の経験ではありません。私にとっては、echo "Happy Birthday!"2行を出力します。1つ目はecho "Happy birthday"(感嘆符なし)、2つ目は「お誕生日おめでとう」(再び感嘆符なし)です。このテストを行うときに、履歴の展開が有効になっていますか?
JWD

@jwdどのバージョンのbashを実行していますか?私は常に歴史的な展開を続けています。誤って2つ使用しましたか!! あなたのテストのために?
h4unt3r 14

@ h4unt3r:、使用されているのversion 4.1.2(1)-release (x86_64-redhat-linux-gnu)は間違いなく1つだけ!です。私はにhistexpand出席してい$SHELLOPTSます。ただし、別のマシンで4.3.18(2)-releaseを試したところ、説明どおりに動作します。修正されたバグだったと思います。
JWD

66

履歴展開をオフにします。

set +H

または

set +o histexpand

~/.bashrc通常、履歴展開を使用しない場合は、これらのコマンドのいずれかを追加できます。

Bash 4.3は特別なケースを追加しました:

二重引用符で囲まれた文字列内の終了二重引用符の直前にある場合、履歴展開文字も引用符として扱われます


おかげで-これはうまくいきましたがset +o histexpand、私はやらなければなりませんでしたset -o histexpand。これを修正するために答えを編集できますか?
マシュー

おっと、タイプミス、ごめんなさい。一定。
デニスウィリアムソン

素晴らしい!AGESでこれを探していました。...thx vm!エスケープ文句を言わない作業として...私はあまりにも単一引用符を使用したくない...私は私にこれを追加します.bashrcTHX !!、決して使用される!スクリプトにし、何のために!それは常に...厄介た
アクエリアスパワー

これはすごい!echo "@AquariusPower!"
ジョエハンナ

12

二重引用符( ")の代わりに単一引用符( ')を使用します。単一引用符は、それらの内容のすべての解釈をオフにしますが、二重引用符は一部のみをオフにします。

bzr commit -m 'It works!'

4

echo感嘆符で区切る必要がある文字列(文)で少なくとも機能する別の方法を見つけました。Bash histexpandを中心にエンドランを実行しますが、コーディングには少し時間がかかります。

http://www.ascii-code.com/にリストされている感嘆符の16進数 は21であるため\x21、文字列の末尾に置くと、独自の拡張エコーをecho -e $foo作成$fooします(つまり、foo=$(echo -e "$foo"))あなたがecho $foo再び文字列で!終わるときに取得します。また、histexpandも切り替えません。

Bash 4+で確実に動作します。以前のバージョン、ymmv。


うーん、それは私には機能しません。
lzap 14年

エコーについてあなたが言っていることはわかりません。'echo -e'および 'printf'は、エスケープされた8進数、16進数、およびUnicodeコードを解釈します。これらのいずれかを使用している場合、感嘆符の代わりに「\ 041」(「!」の8進数)または「\ x21」(16進数)を使用できます。例:printf "OMG\041"。echoまたはprintf以外の場所に二重引用符で囲まれた文字列を作成する場合(コミット文字列OPについての質問$(echo -e "\041")など)、感嘆符のあるべき場所に文字列を埋め込むことができます。このようにbzr commit -m "This is a great commit$(echo -e "\041")"
トッドウォルトン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.