为了加快一些 bash 脚本的执行,我想使用命令替换将命令的结果保存在变量中,但是命令替换用空格替换0x0A换行符。例如:
0x0A
a=`df -H`
或者
a=$( df -H )
当我想进一步处理$a时,换行符被空格替换,所有行现在都在一行上,这更难 grep:
$a
echo $a
避免命令替换删除换行符的简单技巧是什么?
您正在寻找的换行符在那里,您只是看不到它们,因为您使用echo时没有引用变量。
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选项调用它),但在某些极端情况下,程序输出中的尾随换行符不止一个,它们对于一些理由。
-n
在这种情况下,正如@Scrutinizer 所提到的,您可以使用以下解决方法:
$ a=$(printf 'test\n\n'; printf x); a=${a%x} $ echo "$a" test $
说明:*字符x被添加到输出中(使用printf x),在换行符之后。由于换行符不再尾随*,因此它们不会被命令替换删除。下一步是删除x我们添加的,使用%运算符 in${a%x}。现在我们有了原始输出,所有换行符都存在!!!
x
printf x
%
${a%x}
代替使用命令替换将程序的输出分配给变量,我们可以使用进程替换 将程序的输出提供给read内置命令(归功于@ormaaj)。进程替换保留所有换行符。将输出读取到变量有点棘手,但您可以这样做:
read
$ IFS= read -rd '' var < <( printf 'test\n\n' ) $ echo "$var" test $
*解释:*
IFS=
var
-rd ''
r
d ''
代替使用命令或进程替换将程序的输出分配给变量,我们可以将程序的输出通过管道传递给read命令(归功于@ormaaj)。管道还保留所有换行符。但是请注意,这次我们lastpipe使用内置的shopt. 这是必需的,以便read在当前 shell 环境中执行命令。否则,该变量将在子 shell 中分配,并且无法从脚本的其余部分访问。
lastpipe
shopt
$ cat test.sh #!/bin/bash shopt -s lastpipe printf "test\n\n" | IFS= read -rd '' var echo "$var" $ ./test.sh test $