0

假设有一个目录 ' 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之后发现原因是when SUFF='dd',$FILES是一个空字符串,并不是程序真正的null输出,会被认为有一行by wc。NUL 输出只能通过管道传递。所以一种解决方案是:

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

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

4

4 回答 4

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
于 2016-09-28T10:16:44.920 回答
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"
于 2016-09-28T10:13:45.923 回答
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}'1.aa 2.aa 3.aa从 $FILES 变量中获取

wc -w打印字数

于 2016-09-28T10:24:56.243 回答
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[@]}"
于 2016-09-28T10:32:50.363 回答