「echo -e」コマンドで正しい出力が生成されないのはなぜですか?


21

Ubuntu 18.04 LTSのターミナルで、このコマンドを書くと:

echo -e "Hello\\\n"

出力としてこれを提供します:

Hello\n

しかし、manページにあるように、印刷されるはずです。

Hello\

つまり、最初にprint Hello、次に\、次に改行文字(そして別の改行)になります。問題はどこにありますか?

これらのいくつかのecho -eコマンドとその出力を参照してください。

man420@man420-X542UQ:~$ echo -e "HEllo\a\a\a\a\a\a\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\a\\\n"
HEllo\n

yes.for最初の2 \ \を出力する必要があり、最後の\とnはバックスラッシュエスケープを行います\ n(改行)。だからHello \
yolin00

1
引用符なしで試してください。
ajgringo619

2
Eliah Kaganから驚くべき答えが出されましたが、これを受け入れてください。
バナジウム

2
使用しないでくださいecho最初の場所で:使用しますprintf
チェプナー19:52

2
書くものが正確に引数としてコマンドに渡されるものであることを確認したい場合は、常に単一引用符を使用してください。
ジャコモアルゼッタ

回答:


29

バックスラッシュはによって特別に扱われますがecho -e、最初にシェルの引用規則に従って、シェル(この場合は)によって特別に扱われることがあります。bash

echo実際に見る引数はですHello\\nにパスした-eためecho、バックスラッシュエスケープを特別に処理\\し、単一のに折りたたまれ\ます。ファイナルnはエスケープされないため、文字通り表示されます。

この理由はecho、シェルがそれ自体の操作の前に、それとは別に、シェル\特定のコンテキストで特別処理し、他のコンテキストでは処理しないためです。引用符で囲まれていない\文字は常に特別に扱われ、単一引用符で囲まれたが \、特別に扱われることはありませんが、治療の二重引用符で囲まれた \文字は、あなたが走ったコマンドのように、より微妙かつ複雑です。

シェルは、コマンド内で二重引用符で囲まれたテキストを検出すると"Hello\\\n"、それ\自体が二重引用符内で特別な意味を持つことができる文字の前にある場合、エスケープ文字として扱います

  1. \内部""には特別な意味があることがあるため、\別の直前にあるa は\その秒を引用する効果があり\ます。したがって、二重引用符内では、最初の引用符\\はにまとめられ\ます。
  2. 最初の2 \文字の後に、最初の2 文字の\影響を受けず、に先行する3番目の文字がありnます。しかしn、二重引用符内で特別に扱われる文字ではないため、\この状況ではそれ以前は特別に扱われません。したがって、\n残ります\n

その効果は、二重引用符で\\\n囲まれ\\nたものとして解釈されることです。

echo -e見る\\nと、最初のもの\は2番目のものから特別な意味を取り除いているので、そのテキストに対して文字通りecho印刷\nします。


Helloバックスラッシュを使用せずに余分な改行で印刷することが目標である場合(質問はもともとこれについてあいまいでしたが、有用な例だと思います)、1つの解決策はを削除すること\です。最後に余分な改行を使用してecho -e "Hello\\n"出力Helloを実行します。

より良い解決策は、単一引用符を使用してを書くことecho -e 'Hello\n'です。単一引用符は、引用の最も強力な形式です。さらに良い解決策は通常、printf代わりに使用echoすることprintf 'Hello\n\n'です。

Hello\バックスラッシュを含めて印刷し、その後に改行を追加することが目的の場合、二重引用符で囲む方法は可能ですが、面倒です。後方、仕事をそれを把握するには、次のecho -e変換\\\\n改行すると、二重引用符変換を\\\、あなたが6つのバックスラッシュ(でそれを行うことができますのでecho -e "Hello\\\\\\n")、ので\\nターンに\n別のエスケープ1つのバックスラッシュによるもの。がエスケープされていない\n場合でも二重引用符が保持されるため、5でもでき\ます。

これは、echo -e一重引用符の利点を示していますecho -e 'Hello\\\n'。一重引用符()の中に見たいものを入れてください。printfここでも良いです 1つのオプションはprintf 'Hello\\\n\n'です。しかし、printf本当に輝くのは、追加の引数をプラグインできることです。を使用してprintf '%s\n\n' 'Hello\'、のHello\代わりに2番目の引数を挿入できます(文字通り、単一引用符は何も変更しないため)%s

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.