如何避免bash命令替换删除换行符? [英] How to avoid bash command substitution to remove the newline character?

查看:312
本文介绍了如何避免bash命令替换删除换行符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要加快一些bash脚本的执行,我想用命令替换在一个变量保持一个命令的结果,而是命令替换替换的0x0A 换行符由一个空间。例如:

To speed up some bash script execution, I would like to keep the result of a command in a variable using command substitution, but the command substitution replaces the 0x0A newline character by a space. For example:

a=`df -H`

a=$( df -H )

当我想进一步处理 $ A ,换行字符用空格代替现在所有的线路都在一行,这是更难的grep:

When I want to process further $a, the newline characters are replaced by a space and all the lines are now on one line, which is much harder to grep:

echo $a

什么是容易的技巧,以避免换行符的命令替换被删除?

What would be the easy tricks to avoid the newline character being removed by the command substitution?

推荐答案

您正在寻找的换行符在那里,你就看不出来,因为你用回声引用不变量。

Non-trailing newlines are not removed

The newlines you are looking for are there, you just don't see them, because you use echo without quoting the variable.

验证

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 正确地指出,虽然输出内换行不会被删除,结尾的新行的用命令替换删除。请参见下面的实验:

Trailing newlines are removed

As @user4815162342 correctly pointed out, although newlines within the output are not removed, trailing newlines are removed with command substitution. See experiment below:

$ a=$'test\n\n'
$ echo "$a"
test


$ b=$(echo "$a")
$ echo "$b"
test
$

在大多数情况下,这并不重要,因为回声将添加删除换行符(除非它是与调用 -n 选项),但也有一些边缘的情况下有一个以上的在一个程序的输出后的新行,它们是出于某种原因显著。

In most cases this does not matter, because echo will add the removed newline (unless it is invoked with the -n option), but there are some edge cases where there are more that one trailing newlines in the output of a program, and they are significant for some reason.

在这些情况下,为 @Scrutinizer 提到的,可以使用以下解决方法:

In these case, as @Scrutinizer mentioned, you can use the following workaround:

$ a=$(printf 'test\n\n'; printf x); a=${a%x}
$ echo "$a"
test


$ 

说明:字符 X 添加到输出(使用的printf点¯x),新行之后。由于新行不的结尾的更多,他们不会被命令替换删除。下一步是要删除 X 我们添加,使用运营商 $ {一%X} 。现在我们有原始输出,与所有换行present!

Explanation: Character x is added to the output (using printf x), after the newlines. Since the newlines are not trailing any more, they are not removed by the command substitution. The next step is to remove the x we added, using the % operator in ${a%x}. Now we have the original output, with all newlines present!!!

而不是使用命令替换来分配程序的变量输出,我们可以改用进程替换到程序的输出馈送到内置命令(信贷 @ormaaj )。进程替换preserves所有换行符。读取输出给一个变量是有点棘手,但你可以做到这样的:

Instead of using command substitution to assign the output of a program to variable, we can instead use process substitution to feed the output of the program to the read built-in command (credit to @ormaaj). Process substitution preserves all newlines. Reading the output to a variable is a bit tricky, but you can do it like this:

$ IFS= read -rd '' var < <( printf 'test\n\n' ) 
$ echo "$var"
test


$ 

说明:

Explanation:


  • 我们设置内部字段分隔符为读命令空与 IFS = 。否则不完整的输出分配给 VAR ,但只有第一个令牌。

  • 我们调用 与选项 -rd''。在研究是preventing反斜线作为一个特殊的字符,与 D 设置分隔符不了了之,使读取保存整个输出,而不是仅仅在第一线。

  • We set the internal field separator for the read command to null, with IFS=. Otherwise read would not assign the entire output to var, but only the first token.
  • We invoke read with options -rd ''. The r is for preventing the backslash to act as a special character, and with d '' set the delimiter to nothing, so that read reads the entire output, instead of just the first line.

而不是使用命令或进程替换分配程序的变量输出,我们可以改为管道程序的输出到命令(信贷< STRONG> @ormaaj )。管道也preserves所有换行符。但是请注意,这一次我们将 lastpipe 外壳可选行为,使用的the 禁用了javascript 内置。这是必需的,这样命令在当前shell环境中执行。否则,该变量将在子shell分配,并且它不会从脚本的其余部分进行访问。

Instead of using command or process substitution to assign the output of a program to variable, we can instead pipe the output of the program to the read command (credit to @ormaaj). Piping also preserves all newlines. Note however, that this time we set the lastpipe shell optional behavior, using the shopt builtin. This is required, so that the read command is executed in the current shell environment. Otherwise, the variable will be assigned in a subshell, and it will not be accessible from the rest of the script.

$ cat test.sh 
#!/bin/bash
shopt -s lastpipe
printf "test\n\n" | IFS= read -rd '' var
echo "$var"
$ ./test.sh 
test


$

这篇关于如何避免bash命令替换删除换行符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆