假设有一个目录“ 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
命令被执行两次。所以我的问题是:有没有更优雅的方法来实现这个目标?
答案 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[@]}"