シェル内の単一引用符をエスケープする方法はありますか?


11

例 私は言いたい

perl -e 'print '"'"'Hello, world!'"'"', "\n";'

一重引用符をエスケープするなど、それほど厄介な方法はありますか?

はい、私は書くことができることを知っています

perl -e 'print q[Hello, world!], "\n"'
perl -e 'print "Hello, world!\n"'

しかし、この質問は、Perlではなくシェルで引用することに関するものです。

私はそれを行うにはどのように興味bashcsh最初の場所で。

回答:


9

デニスは彼の答えで通常の代替案を指摘しています(シングルインダブル、ダブルインシングル、エスケープされたシングルクォートで連結されたシングルクォートされた文字列;あなたはすでにPerlのカスタマイズ可能なクォート演算子に言及しました)にとって。

Bourneのようなシェル(sh、ksh、ash、dash、bash、zshなど)では、単一引用符で囲まれた文字列は完全にリテラルです。これにより、シェルがエスケープせずに特別に処理する文字を簡単に含めることができますが、単一引用符文字自体を単一引用符付き文字列に含めることはできません。

cshタイプのシェルは他の点で完全に壊れているので、私も考えることを拒否します(Cshプログラミングが有害と見なされるを参照)。


ありがとうございました。「これは不可能です」-それは私が期待した答えです:)私は常に、この役割を果たすことに専念する文書がここにあることを望んでいました。
共産主義

Perlとは異なり、Bourneのようなシェルのここにあるドキュメントは、stdinを介して入力を提供する場合にのみ直接役立ちます。もちろん、それらに単一引用符を入れることができます。(例):あなたはまた、言葉を引用して、ここでドキュメントの「リテラルモード」を有効にすることができますblah <<\EOF … EOF<<'EOF'およびを使用することもできます<<"EOF。それらはすべて、Perlとは異なり、リテラルのhereドキュメントを意味します。あなたが本当に決心していれば、あなたはすることができますblah "$(cat<<\EOF … EOF )" other args(コマンド置換でスペースを書いた改行を使用して、kshとzshはcatなしでできますが、他の人はそれを必要とします)。しかし、それは本当に価値があるでしょうか?
クリスジョンセン

zshの単一引用符は文字通りではないことに注意してください。Zshは、一重引用符で囲まれた文字列内の任意の場所の '\ U'を文字コードとして解釈しようとします(例:echo '\U0000068\U000069'echo 'hi')。ただし、シェルのバグでない限り、理由はわかりません。
マシュー

1
@Matthew:\Uその場合の解釈は、組み込みのechoコマンドによって行われます(この動作は、-EまたはBSD_ECHOオプションとによって制御できます-e)。リテラル文字列が他のコマンドで渡されている(他の方法で解釈されていない)ことがわかります。例えばprintf %s\\n '\U0000068\U000069'
クリスジョンセン

@ChrisJohnsenありがとう、私はzshが初めてで、これに気付いていませんでしたが、あなたは正しいです。manページには-eがデフォルトであると書かれていますが、zshはそれをオーバーライドする必要があります。
マシュー

5

私にとって、あなたのすべての例は以下を生成します:

こんにちは世界!

これも同様です。

perl -e 'print "Hello, world!", "\n";'

この:

perl -e 'print '\''Hello, world!'\'', "\n";'

何をしようとしているのか明確にできますか?

Bashなどのシェルでは、文字列の一部として引用符を印刷する場合、1種類の引用符が他の引用符をエスケープします。

$ echo '"Hello, world!"'
"Hello, world!"
$ echo "'Hello, world!'"
'Hello, world!'

編集:

別の方法を次に示します。

$ perl -e 'print "\047Hello, world!\047", "\n";'
'Hello, world!'
$ echo -e "\047Hello, world! \047"
'Hello, world! '

感嘆符の後のスペースは、履歴展開エラーを回避します。set +H代わりにできたかもしれません。


1

前の回答の編集内容が表示されるかどうかわからない:

新しい回答と同じ貼り付け:

別のアプローチ:

私があなたの解決策を試みたとき、私はまだ印刷することができませんでした。

しかし、私はあなたの解決策から手掛かりを取り、以下を試しました:

$ perl -e '$foo = chr(39); print "${foo}Hello, world ${foo}", "\n";'
'Hello, world '

'のASCII値は39です。

関心のある場所に 'を追加するために、一連のファイルをインライン編集するためにこれが必要でした。


1

ここで、エスケープを気にしないための最良の方法がここにあります。

$ cat <<EOF
my $var = "Hello";
print $text, ', world!', "\n";'
EOF

引用されたこちらのドキュメントを使用して、すべての拡張を完全に禁止することができます。

$ cat <<'EOF'
my $var = "Hello";
print $text, ', world!', "\n";'
EOF

入力の代わりに引数として渡したい場合は、xargsを使用できます。

$ xargs -0 <<'EOF' perl -e
my $var = "Hello";
print $text, ', world!', "\n";'
EOF

0

bashでこれを行うオプションがあるかどうかはわかりませんが、zsh ''では、RC_QUOTESオプションをオンにした後に使用できます。(zshを試すことをお勧めします。ほとんどの場合、bashと互換性があり、さらに互換性を保つためにbashをエミュレートできます。)

bash(および、ほとんどの場合はzsh)では、を使用する'\''よりも読みやすいので使用しています'"'"'

私はcshでそれを行う方法がまったくわかりません。


-1

内部でperlスクリプトの一部として使用されている場合は、\ 'と\ "を使用してperlで引用符をエスケープできます。コマンドラインがそれを受け入れるかどうかはわかりません。


3
それがとても簡単だったら、私は尋ねないだろう。回答を投稿する前に、試してみて、機能するかどうかを確認できます。
コードホリック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.