web-dev-qa-db-ja.com

エコーを使用するときに新しい行を追加する方法

次のコマンドで、生成されたファイルに新しい行が挿入されないのはなぜですか?解決策は何ですか?

$ echo "Line 1\r\nLine2" >> readme.txt

$ cat readme.txt 
Line 1\r\nLine2
46
Saeid Yazdani

echo


Single Unix Specificationに厳密に準拠するecho実装は、次の場合に改行を追加します。

_echo 'line1\nline2'
_

しかし、これは信頼できる動作ではありません。実際、実際にechoに期待できるではない標準的な動作があります。

[〜#〜]オペランド[〜#〜]

string

標準出力に書き込まれる文字列。最初のオペランドが_-n_の場合、またはいずれかのオペランドに<_\_ backslash>文字が含まれている場合、結果は実装定義です。

XSI-conformant システムでは、最初のオペランドが_-n_の場合、文字列として扱われますオプションではありません。以下の文字シーケンスは、XSI準拠のシステムで、引数のいずれか内で認識されます。

_\a_-<alert>を書き込みます。

_\b_-<backspace>を書き込みます。

_\c_-出力の最後の引数の後に続く<newline>を抑制します。引数の_\c_に続くすべての文字は無視されます。

_\f_-<form-feed>と記述します。

_\n_-<newline>と記述します。

_\r_-<carriage-return>を書き込みます。

_\t_-<tab>と書き込みます。

_\v_-<vertical-tab>を書き込みます。

_\\_-<backslash>文字を書き込みます。

_\0num_-ゼロ、1、2、または3桁の8進数numである8ビット値を書き込みます。

そのため、echoを使用して改行を記述する一般的な方法は実際にはありませんが、echoを実行するだけで通常はそうすることができます。

bashシェルは通常、notを仕様に準拠させ、_-n_およびその他のオプションを処理しますが、それも不確かです。できるよ:

_shopt -s xpg_echo
echo hey\\nthere
_

_hey
there
_

そして、それでもないは、bashがビルド時オプションでビルドされている場合に必要です...

_--enable-xpg-echo-default_

_-e_オプションを必要とせず、echoビルトインがデフォルトでバックスラッシュエスケープ文字を展開するようにします。これにより、_xpg_echo_シェルオプションのデフォルト値がonに設定され、Bashがechoになります。 Single Unix Specification、バージョン3で指定されたバージョンのように動作します。echoが認識するエスケープシーケンスの説明については、「 Bash Builtins 」を参照してください。


printf


一方、printfの動作は、比較するとかなりなめらかです。

[〜#〜]根拠[〜#〜]

printfユーティリティは、これまでechoによって提供されていた機能を提供するために追加されました。ただし、echoのさまざまなバージョンが存在する不一致の違いが原因で、バージョンにはいくつかの特別な機能があり、Ninth Editionシステムの機能に基づいたこの新しいprintfユーティリティにそれらを残しています。

拡張説明セクションは、ISO C標準の printf() 関数とほぼ正確に一致しますが、 XBDファイル形式表記 のファイル形式表記。

引数を説明するフォーマット文字列を処理します。引数はいくつでもかまいませんが、文字列の場合は、ほぼ_%b_ yte文字列またはリテラル_%s_ tringsのいずれかです。最初の引数の_%f_ ormats以外は、_%b_エスケープを処理しないことを除いて、_\c_ yte文字列引数とほとんど同じように動作します。

_printf ^%b%s$ '\n' '\n' '\t' '\t'
_

_^
\n$^    \t$
_

詳細は printfechoより優れている理由 を参照してください。


echo() printf


独自の標準に準拠したechoのように書くことができます...

_echo(){
    printf '%b ' "$@\n\c"
}
_

...ほとんどの場合、自動的に適切な処理が行われます。

実際、いいえ...最後の引数が奇数の<backslashes>で終わる場合、引数の末尾にリテラル_\n_を出力します。

しかし、これはしません:

_echo()
    case    ${IFS- } in
    (\ *)   printf  %b\\n "$*";;
    (*)     IFS=\ $IFS
            printf  %b\\n "$*"
            IFS=${IFS#?}
    esac
_
43
mikeserv

-eフラグをechoに渡して、「\ r\n」などのエスケープ文字を解析できるようにします。

echo -e "Line 1\r\nLine2" >> readme.txt
29
Hayden Schiff

私が使用したすべてのバージョンのbashでは、文字列が十分に引用符で囲まれていれば、対話的にまたはスクリプトで文字列にリテラルの改行を挿入できます。

インタラクティブに:

$ echo "Line one
> Line two"
Line one
Line two
$

スクリプトで:

echo "Line one
Line two"
8
Digital Trauma
echo -e "Line 1\r\nLine2" >> readme.txt

さらなる使用の可能性:

man echo
4
zodo

人々はすでに十分に答えていますが、エコーが-n以外のオプションを受け入れる世界を受け入れることを拒否します。

nl='
'
echo Line 1"$nl"Line 2"$nl"Line 3
2
Staven

メッセージの一部ではない文字がある場合は、sedをパイプ処理できます

$ echo "Time on the next line:@$(date +"%Y-%m-%dT%T%z")" | sed -e's/@/\n/g'
Time on the next line:
2016-03-25T10:12:39-0500
1
verisimilidude

使用する

echo -e "line1\nline2"

これにより、新しい行が印刷されます。

0
Sudhir