2016-09-28 36 views
0

假设有一个目录“”它包含几个文件:如何在bash脚本中存储程序的NUL输出?

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

的文件名以'foo'结束?你可以给一个这样的样本名称吗?你想递归搜索子目录吗? – Inian

+0

foo是目录。文件名以aa,bb,cc结尾。不需要搜索子目录。 – xlwang

回答

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 
+0

很好的解释! – 123

+3

@ 123:这很有趣,我没有写。你最近去过眼科医生吗? –

+0

是否有一种简单的方法逐个输出文件的内容? – xlwang

0

如果你只需要文件的数量,我会实际使用find为:

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

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

编辑:如果你想保持在一个阵列的文件列表,你可以使用水珠:

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

但我也希望稍后在脚本中输出这些文件的名称。 – xlwang

+1

@Inian你是什么意思? – redneb

+0

@Inian它确实是因为它们只为每个文件名输出一个换行符,而不是实际的文件名 – 123

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 ':' '{打印$ 2}' 从$ FILES变量

wc -w打印变得1.aa 2.aa 3.aa字计数

0

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

如果未找到匹配的文件名,并且未启用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[@]}" 
+0

Thx。但是,如果文件名包含\ n,则可能会失败。 – xlwang

+0

@xlwang好的,解决了。 '%.0s \ n'每个文件只打印一行。 – sorontar