如何避免bash命令replace删除换行符?
为了加速一些bash脚本的执行,我想使用命令replace将一个命令的结果保存在一个variables中,但是命令replace将0x0A
换行符replace为一个空格。 例如:
a=`df -H`
要么
a=$( df -H )
当我想进一步处理$a
,换行符会被一个空格replace,所有的行现在都在一行上,这对grep来说更加困难:
echo $a
避免换行符被删除的简单技巧是什么?
非尾随换行符不会被删除
你正在寻找的换行符在那里,你只是没有看到它们,因为你使用echo
没有引用variables。
validation :
$ 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正确指出的那样,虽然输出中的换行符不会被删除,但换行符后面的换行符会被replace掉。 看下面的实验:
$ a=$'test\n\n' $ echo "$a" test $ b=$(echo "$a") $ echo "$b" test $
在大多数情况下,这并不重要,因为echo
会添加除去的换行符(除非它是用-n
选项调用的),但是在程序的输出中还有一些边缘情况的尾随换行符,由于某种原因是重要的。
解决方法
1.添加虚拟angular色
在这种情况下,正如@Scrutinizer所提到的,您可以使用以下解决方法:
$ a=$(printf 'test\n\n'; printf x); a=${a%x} $ echo "$a" test $
说明:字符x
被添加到输出(使用printf x
),在换行符之后。 由于换行符不再拖曳 ,它们不会被命令replace删除。 下一步是使用${a%x}
的%
运算符来移除我们添加的${a%x}
。 现在我们有原始输出,所有换行符都在场!
2.使用进程replace进行读取
而不是使用命令replace来将程序的输出分配给variables,我们可以改为使用进程replace来将程序的输出提供给read
内置命令(记入@ormaaj )。 进程replace保留所有换行符。 读取输出到一个variables有点棘手,但你可以这样做:
$ IFS= read -rd '' var < <( printf 'test\n\n' ) $ echo "$var" test $
说明:
- 我们将读命令的内部字段分隔符设置为空,其中
IFS=
。 否则,read
不会将整个输出分配给var
,而只会分配第一个标记。 - 我们用选项
-rd ''
调用read
。r
用于防止反斜杠作为特殊字符,并用d ''
将分隔符设置为空,以便读取读取整个输出,而不是仅读取第一行。
3.从pipe道读取
而不是使用命令或进程replace来将程序的输出分配给variables,而是将程序的输出传递给read
命令(信任给@ormaaj )。 pipe道也保留所有换行符。 但是请注意,这次我们使用shopt
内置的方法设置了lastpipe
shell的可选行为。 这是必需的,以便read
命令在当前shell环境中执行。 否则,variables将被分配在一个子shell中,并且不能从脚本的其余部分访问。
$ cat test.sh #!/bin/bash shopt -s lastpipe printf "test\n\n" | IFS= read -rd '' var echo "$var" $ ./test.sh test $
我试图把我的头围绕着这个,因为我正在使用bash在F#脚本上运行解释器的结果stream。 经过一些反复试验,结果发现解决了这个问题:
$ 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
假设你当然需要运行一个terminal程序。 希望这可以帮助。