web-dev-qa-db-ja.com

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

例:私は言いたい

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

それを行うためのそれほど厄介な方法はありません。 g。一重引用符をエスケープしますか?

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

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

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

そもそもbashcshでそれを行う方法に興味があります。

11
codeholic

デニスは彼の答えの中で通常の選択肢を指摘しています(シングルインダブル、ダブルインシングル、エスケープされた一重引用符で連結された一重引用符文字列;あなたはすでにPerlのカスタマイズ可能な引用演算子について言及しました)、しかしおそらくこれはあなたが探していた直接の答えですにとって。

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

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

9
Chris Johnsen

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

こんにちは世界!

そしてこれもそうです:

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

この:

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

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

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

$ 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代わりに。

前の回答に対する私の編集が表示されるかどうかわからない:

新しい回答と同じように貼り付けます。

代替アプローチ:

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

しかし、私はあなたの解決策からヒントを得て、以下を試しました:

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

'のASCII値は39です。

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

1
Kaushik B

ここにドキュメントはエスケープを気にしないための最良の方法です:

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

引用されたhereドキュメントを使用して、すべての拡張を完全に初期化できます。

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

入力ではなく引数として渡したい場合は、xargsを使用できます。

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

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

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

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