如何在 bash 脚本中存储程序的 NUL 输出?

How to store NUL output of a program in bash script?

假设有一个目录 'foo' 包含几个文件:

ls foo:
1.aa 2.bb 3.aa 4.cc

现在在 bash 脚本中,我想计算 'foo' 中具有特定后缀的文件的数量,并显示它们,例如:

SUFF='aa'
FILES=`ls -1 *."$SUFF" foo`
COUNT=`echo $FILES | wc -l`
echo "$COUNT files have suffix $SUFF, they are: $FILES"

问题是:如果SUFF='dd'$COUNT也等于1。在google之后,我找到的原因是SUFF='dd'时,$FILES是一个空字符串,并不是真正的程序的null输出,[=19会认为有一行=]. NUL 输出只能通过管道传递。所以一种解决方案是:

COUNT=`ls -1 *."$SUFF" foo | wc -l`

但这会导致ls命令被执行两次。所以我的问题是:有没有更优雅的方法来实现这个?

如果您只需要文件数,我实际上会使用 find

find '/path/to/directory' -mindepth 1 -maxdepth 1 -name '*.aa' -printf '\n' | wc -l

这更可靠,因为它可以正确处理带换行符的文件名。其工作方式是 find 为每个匹配文件输出一个空行。

编辑:如果要将文件列表保存在数组中,可以使用 glob:

GLOBIGNORE=".:.."
shopt -s nullglob
FILES=(*aa)
COUNT=${#arr[@]}
echo "$COUNT"
$ shopt -s nullglob
$ FILES=(*)
$ echo "${#FILES[@]}"
4
$ FILES=(*aa)
$ echo "${#FILES[@]}"
2
$ FILES=(*dd)
$ echo "${#FILES[@]}"
0
$ SUFFIX=aa
$ FILES=(*"$SUFFIX")
$ echo "${#FILES[@]}"
2
$ SUFFIX=dd
$ FILES=(*"$SUFFIX")
$ echo "${#FILES[@]}"
0

你也可以试试这个;

#!/bin/bash
SUFF='aa'
FILES=`ls -1 *."$SUFF" foo`
FILENAMES=`echo $FILES | awk -F ':' '{print }'`
COUNT=`echo $FILENAMES | wc -w`
echo "$COUNT files have suffix $SUFF, they are: $FILENAMES"

如果在你的脚本中插入 echo $FILES,输出是 foo: 1.aa 2.aa 3.aa 所以

awk -F ':' '{print $2}' 从 $FILES 变量

获取 1.aa 2.aa 3.aa

wc -w 打印字数

原因是 bash 中默认未设置选项 nullglob:

If no matching file names are found, and the shell option nullglob is not enabled, the word is left unchanged. If the nullglob option is set, and no matches are found, the word is removed.

因此,只需设置 nullglob 选项,然后 运行 您再次编码:

shopt -s nullglob
SUFF='aa'
FILES="$(printf '%s\n' foo/*."$SUFF")"
COUNT="$(printf '%.0s\n' foo/*."$SUFF" | wc -l)"
echo "$COUNT files have suffix $SUFF, they are: $FILES"

或者更好:

shopt -s nullglob
suff='aa'
files=( foo/*."$suff" )
count=${#file[@]}
echo "$count files have suffix $suff, they are: ${files[@]}"