いくつかのbashスクリプトの実行を高速化するために、コマンド置換を使用して変数にコマンドの結果を保持したいのですが、コマンド置換は0x0A
改行文字をスペースに置き換えます。例えば:
a=`df -H`
または
a=$( df -H )
$a
をさらに処理したい場合、改行文字はスペースに置き換えられ、すべての行が1行になります。これはgrepがはるかに困難です。
echo $a
コマンド置換によって改行文字が削除されるのを避けるための簡単なトリックは何でしょうか?
探している改行はそこにあります。変数をクォートせずに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
オプションで呼び出されない限り)、ほとんどの場合、これは重要ではありませんが、末尾に改行が複数あるEdgeの場合があります。プログラムの出力であり、何らかの理由で重要です。
これらの場合、@ Scrutinizerで述べたように、次の回避策を使用できます。
$ a=$(printf 'test\n\n'; printf x); a=${a%x}
$ echo "$a"
test
$
説明:文字x
が出力に追加されます(printf x
を使用) )、改行の後。改行は末尾ではないため、コマンド置換によって削除されません。次のステップは、%
の${a%x}
演算子を使用して、追加したx
を削除することです。これで、すべての改行が存在する元の出力ができました!!!
コマンド置換を使用してプログラムの出力を変数に割り当てる代わりに、代わりに process substitution を使用して、 read
組み込みコマンドへのプログラム(@ ormaajへのクレジット)。プロセス置換により、すべての改行が保持されます。出力を変数に読み込むのは少し難しいですが、次のようにすることができます。
$ IFS= read -rd '' var < <( printf 'test\n\n' )
$ echo "$var"
test
$
説明:
IFS=
でnullに設定します。そうでない場合、read
は出力全体をvar
に割り当てず、最初のトークンのみを割り当てます。read
をオプション-rd ''
で呼び出します。 r
は、バックスラッシュが特殊文字として機能するのを防ぐためのものであり、d ''
で区切り文字を何も設定しないため、readは最初の行だけでなく出力全体を読み取ります。コマンドまたはプロセスの置換を使用してプログラムの出力を変数に割り当てる代わりに、プログラムの出力をread
コマンド(@ ormaaj)。配管もすべての改行を保持します。ただし、今回は the lastpipe
builtin を使用して、shopt
Shellオプション動作を設定します。これは、read
コマンドが現在のシェル環境で実行されるために必要です。それ以外の場合、変数はサブシェルで割り当てられ、残りのスクリプトからはアクセスできません。
$ cat test.sh
#!/bin/bash
shopt -s lastpipe
printf "test\n\n" | IFS= read -rd '' var
echo "$var"
$ ./test.sh
test
$
F#スクリプトでインタープリターを実行した結果をストリーミングするためにbashを使用していたため、これに頭を悩まそうとしていました。いくつかの試行錯誤の後、これは問題を解決することが判明しました。
$ cat fsi.ch
#!/bin/bash
echo "$(fsharpi --quiet --exec --nologo $1)"
$ fsi.ch messages.fsx
Welcome to my program. Choose from the menu:
new | show | remove
もちろん、ターミナルプログラムを実行する必要があると仮定します。お役に立てれば。