我正在尝试将单个输出流传递到zcat
bash 管道中。让我们将其用作wc -l
此示例的管道。
zcat -f /var/log/log.3.gz /var/log/log.2.gz /var/log/log.1.gz /var/log/log | wc -l
实际上返回的是行数。
paths="/var/log/log.3.gz /var/log/log.2.gz /var/log/log.1.gz /var/log/log"
zcat -f "${paths}" | wc -l
gzip: /var/log/log.3.gz /var/log/log.2.gz /var/log/log.1.gz /var/log/log.gz: 没有这样的文件或目录
如何将所有这些文件合并到标准输出,以便我的管道只进行一次传递而无需中间文件?我尝试传递整个字符串结果.gz
附加到变量,就好像这是单个参数一样
答案1
var=('first value' 'second value'...)
列表使用中的语法进行分配bash
。
paths=(/var/log/log.3.gz /var/log/log.2.gz /var/log/log.1.gz /var/log/log)
zcat -f -- "${paths[@]}" | wc -l
请注意, of$path
包含一个空列表,zcat -f -- "${paths[@]}"
将成为zcat -f --
并且当未传递任何文件名参数时,zcat
将读取其标准输入而不是根本不产生任何输出。
要解决这个问题,您可以这样做:
{ (( ${#paths[@]} == 0 )) || zcat -f -- "${paths[@]}"; } | wc -l
或者:
zcat -f -- </dev/null "${paths[@]}" | wc -l
如果您想/var/log/log*
以相反的数字顺序连接文件,您宁愿使用 shell zsh
,而bash
不是执行以下操作:
zcat -f /var/log/log*(nOn) | wc -l
(这是ame 的n
umerical o
rder(O
反向大写)n
)。
并且不需要上述的解决方法;如果没有匹配的文件,你会得到:
$ zcat -f /var/log/log*(nOn) | wc -l
zsh: no matches found: /var/log/log*(nOn)
0
答案2
不加引号的变量将使 shell 执行分词和文件名生成。由于您只想要第一个效果,因此可以禁用后者:
paths="/var/log/log.3.gz /var/log/log.2.gz /var/log/log.1.gz /var/log/log"
(
set -f
zcat -f $paths | wc -l # variable is unquoted
)
我添加了括号,因此该设置仅在该子 shell 的生命周期内有效。
显然,允许 shell 进行分词意味着如果任何路径名包含空格,它就会中断。