末尾の改行以外は削除されません
探している改行はそこにありますがecho
、変数を引用せずに使用しているため、表示されません。
検証:
$ a=$( df -H )
$ echo $a
Filesystem Size Used Avail Use% Mounted on /dev/sda3 276G 50G 213G 19% / udev 2.1G 4.1k 2.1G 1% /dev tmpfs 832M 820k 832M 1% /run none 5.3M 0 5.3M 0% /run/lock none 2.1G 320k 2.1G 1% /run/shm
$ echo "$a"
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 276G 50G 213G 19% /
udev 2.1G 4.1k 2.1G 1% /dev
tmpfs 832M 820k 832M 1% /run
none 5.3M 0 5.3M 0% /run/lock
none 2.1G 320k 2.1G 1% /run/shm
$
末尾の改行は削除されます
@ user4815162342 が正しく指摘したように、出力内の改行は削除されませんが、末尾の改行はコマンド置換で削除されます。以下の実験を参照してください。
$ a=$'test\n\n'
$ echo "$a"
test
$ b=$(echo "$a")
$ echo "$b"
test
$
ほとんどの場合echo
、削除された改行が追加されるため (-n
オプションで呼び出されない限り)、これは問題ではありませんが、プログラムの出力に末尾の改行が複数ある場合がいくつかあり、それらはプログラムにとって重要です。何らかの理由。
回避策
1.ダミーキャラ追加
このような場合、@Scrutinizerが述べたように、次の回避策を使用できます。
$ a=$(printf 'test\n\n'; printf x); a=${a%x}
$ echo "$a"
test
$
説明:改行の後に ( を使用して)文字x
が出力に追加されprintf x
改行はもはや末尾にないため、コマンド置換によって削除されません。次のステップは、演算子 inx
を使用して、追加した を削除するです。これで、すべての改行が存在する元の出力が得られました!!!%
${a%x}
2. プロセス置換を使用して読み取る
コマンド置換を使用してプログラムの出力を変数に割り当てる代わりに、プロセス置換 を使用してプログラムの出力をread
組み込みコマンドにフィードできます ( @ormaajの功績による)。プロセス置換では、すべての改行が保持されます。出力を変数に読み取るのは少しトリッキーですが、次のように実行できます。
$ IFS= read -rd '' var < <( printf 'test\n\n' )
$ echo "$var"
test
$
説明:
- 読み取りコマンドの内部フィールド区切り文字を null に設定し
IFS=
ます。そうread
しないと、出力全体が に割り当てられvar
ず、最初のトークンのみが割り当てられます。
read
options で呼び出します-rd ''
。はr
、バックスラッシュが特殊文字として機能するのを防ぎ、d ''
区切り文字を何も設定しないようにするためのものです。これにより、 read は最初の行だけでなく、出力全体を読み取ります。
3. パイプから読み取る
コマンドまたはプロセス置換を使用してプログラムの出力を変数に代入する代わりに、プログラムの出力をread
コマンドにパイプすることができます ( @ormaajの功績)。パイピングはすべての改行も保持します。ただし、今回はビルトインを使用して、シェルのオプションの動作を設定したことに注意してlastpipe
ください。これは、現在のシェル環境でコマンドを実行するために必要です。それ以外の場合、変数はサブシェルで割り当てられ、残りのスクリプトからアクセスできなくなります。shopt
read
$ cat test.sh
#!/bin/bash
shopt -s lastpipe
printf "test\n\n" | IFS= read -rd '' var
echo "$var"
$ ./test.sh
test
$