给出以下 bash 代码
grep match_nothing file.txt | wc -l
Run Code Online (Sandbox Code Playgroud)
结果0是正确的。但是下面的代码
LINES=$(grep match_nothing file.txt)
wc -l <<< "$LINES"
Run Code Online (Sandbox Code Playgroud)
将返回 1。为什么会发生这种情况以及我该如何纠正。
更新:
这个问题只是grep作为一个例子。让我困惑的是为什么将输出分配给变量会导致不同的结果。
关于:
为什么会发生这种情况
Here-string 的目的是将字符串转换为工具可以作为输入读取的内容,就像读取文件一样,并且根据 POSIX,有效的文本文件始终以换行符结尾,因此here-string 构造在字符串末尾添加换行符。如果它不这样做,那么它的输出将不是有效的 POSIX 文本“文件”,因此您无法可靠地将它用作任何文本处理工具(例如 sed、awk 等)的输入。
关于:
我怎样才能做对
它已经是正确的,但如果您不想添加换行符,则使用带有 a 的命令替换printf来生成输入:
$ lines=''
$ wc -l <<< "$lines"
1
$ wc -l < <(printf '%s' "$lines")
0
Run Code Online (Sandbox Code Playgroud)
但请注意,关于各种工具如何处理它,输出不是每个 POSIX 和 YMMV 的有效文本文件,例如给定非空字符串:
$ lines='foo'
Run Code Online (Sandbox Code Playgroud)
典型的预期行为将由此处的字符串提供:
$ wc -l <<< "$lines"
1
$ while IFS= read -r var; do echo "$var"; done <<< "$lines"
foo
Run Code Online (Sandbox Code Playgroud)
使用带有 a 的命令替换printf可能不是您所期望的:
$ wc -l < <(printf '%s' "$lines")
0
$ while IFS= read -r var; do echo "$var"; done < <(printf '%s' "$lines")
$
Run Code Online (Sandbox Code Playgroud)
如果您想提供在填充变量时添加换行的输入,但在其他情况下不添加换行,那么您可以考虑类似以下内容:
$ lines=''
$ wc -l < <(printf '%s' "$lines"; (( ${#lines} )) && printf '\n')
0
$ while IFS= read -r var; do echo "$var"; done < <(printf '%s' "$lines"; (( ${#lines} )) && printf '\n')
$
Run Code Online (Sandbox Code Playgroud)
$ lines='foo'
$ wc -l < <(printf '%s' "$lines"; (( ${#lines} )) && printf '\n')
1
$ while IFS= read -r var; do echo "$var"; done < <(printf '%s' "$lines"; (( ${#lines} )) && printf '\n')
foo
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
104 次 |
| 最近记录: |