次のコマンドで、生成されたファイルに新しい行が挿入されないのはなぜですか?解決策は何ですか?
$ echo "Line 1\r\nLine2" >> readme.txt
$ cat readme.txt
Line 1\r\nLine2
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
がビルド時オプションでビルドされている場合に必要です...
_
-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$
_
詳細は printf
がecho
より優れている理由 を参照してください。
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
_
-eフラグをechoに渡して、「\ r\n」などのエスケープ文字を解析できるようにします。
echo -e "Line 1\r\nLine2" >> readme.txt
私が使用したすべてのバージョンのbashでは、文字列が十分に引用符で囲まれていれば、対話的にまたはスクリプトで文字列にリテラルの改行を挿入できます。
インタラクティブに:
$ echo "Line one
> Line two"
Line one
Line two
$
スクリプトで:
echo "Line one
Line two"
echo -e "Line 1\r\nLine2" >> readme.txt
さらなる使用の可能性:
man echo
人々はすでに十分に答えていますが、エコーが-n
以外のオプションを受け入れる世界を受け入れることを拒否します。
nl='
'
echo Line 1"$nl"Line 2"$nl"Line 3
メッセージの一部ではない文字がある場合は、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
使用する
echo -e "line1\nline2"
これにより、新しい行が印刷されます。