改行を含む変数を印刷すると最後の改行が削除されるのはなぜですか? [コピー]

改行を含む変数を印刷すると最後の改行が削除されるのはなぜですか? [コピー]

file.txtの内容(当然のことながら、POSIX定義のテキストファイル)

iguana
gecko
anole

スクリプト例:

#!/bin/sh

string="$(cat file.txt)"

printf '%s' "$string"

出力例:

[coolguy@somemachine ~]$ ./script.sh
iguana
gecko
anole[coolguy@somemachine ~]$

最後の改行文字はどうなりますか?最後の保留を除くすべての改行はなぜですか?改行がすでにある場合は、改行を追加するためにechoを使用する必要はないようです。

ベストアンサー1

これは印刷ではなくコマンドの置き換えです。そうするように定義されています。 ~からPOSIXの説明:

シェルはサブシェル環境でコマンドを実行し、コマンド置換をコマンドの標準出力に置き換えてコマンド置換を拡張する必要があります。置換の最後から 1 つ以上の {newline} 文字シーケンスを削除します。

削除されます。みんな末尾の改行文字は一つではありません。

通常、コマンド置換を使用して単一の出力ラインをキャプチャできます。たとえば、osrev=$(uname -r)これらのユーティリティは通常、コマンドラインからユーザーの便宜のために末尾の改行文字を印刷します。ただし、シェルスクリプトでは、その文字列をファイル名などの他の文字列の一部として使用したい場合がありますfilename=blahblah-$osrev.dat。この場合、末尾の改行文字は問題だけを引き起こすだけです。

もちろん、プレーンテキストはechoとにかく最終改行文字を追加します。


変数のファイル内容をそのまま存在させるには、一般的な回避策はコマンド置換に追加の文字を追加してから削除することです。

printf "foo\nbar\n\n" > file
string=$(cat file; echo x)
string=${string%x}
printf '%q\n' "$string"

$'foo\nbar\n\n'2つの末尾の改行を示す出力です。


データとして実行したい操作によっては異なる方法があります。たとえば、ファイルを1行ずつ処理するには、while readループまたはBashを使用できます。mapfile

おすすめ記事