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

时间:2016-09-28 10:11:10

标签: bash output store nul

假设有一个目录“ 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。谷歌之后,我找到的原因是SUFF='dd'$FILES是一个空字符串,而不是程序的空输出,它将被视为wc之一。 NUL输出只能通过管道传递。所以一个解决方案是:

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

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

4 个答案:

答案 0 :(得分:2)

$ 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

答案 1 :(得分:0)

如果您只需要文件计数,我实际上会使用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"

答案 2 :(得分:0)

你也可以试试这个;

#!/bin/bash
SUFF='aa'
FILES=`ls -1 *."$SUFF" foo`
FILENAMES=`echo $FILES | awk -F ':' '{print $2}'`
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打印单词计数

答案 3 :(得分:0)

原因是默认情况下bash中没有设置nullglob选项:

  

如果找不到匹配的文件名,并且未启用shell选项nullglob,则该字保持不变。如果设置了nullglob选项,但未找到匹配项,则删除该单词。

因此,只需设置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[@]}"