bash:计算文件数量时出错并比较

时间:2016-02-06 03:54:44

标签: bash

我是bash脚本的新手。我想使用ls比较我在另一个目录中的文件数。然后我需要将那里的文件数量与我拥有的变量进行比较。

if [ (cd reports_dir/ && ls) | wc  -gt $MAXIMUM_REPORTS ]; then
    echo hello
fi

此代码提供错误:

./monitor.sh: line 70: syntax error near unexpected token `cd'
./monitor.sh: line 70: `    if [(cd reports_dir/ && ls) | wc  -gt $MAXIMUM_REPORTS]; then'

我知道为什么cd出乎意料。当我在终端中运行命令时,(cd reports_dir/ && ls) | wc命令有效。

此命令将在while循环中运行,因此将重复调用它。因此,当我尝试cd不止一次时,我实际上无法进入该目录,从而导致错误。

3 个答案:

答案 0 :(得分:5)

techraf's helpful answer解释了OP方法的问题,并提供了基于ls的有效解决方案。

由于在这种情况下只需要计算文件,因此ls ... | wc -l的使用应该按预期工作;但是, 通常优先使用Bash 中的路径名扩展(globbing):

  • Globbing可以安全地用于收集数组中的文件名并驱动for循环。
  • Globbing,因为它是Bash内部功能,比使用ls(一个外部实用程序)更有效。

以下解决方案演示了使用路径名扩展(globbing)作为ls的替代方法:

注意:默认情况下,globbing不包含隐藏文件;设置shopt -s dotglob(暂时)以包含它们。

if (( $(shopt -s nullglob; set -- reports_dir/*; echo $#) > $MAXIMUM_REPORTS )); then
    echo hello
fi
  • shopt -s nullglob确保在目录为空的情况下不返回任何内容。
  • set -- reports_dir/*将位置参数($1,...)设置为路径名扩展的结果。
  • $#返回设置参数的计数,在这种情况下反映了文件的数量。

答案 1 :(得分:3)

该命令失败,因为您需要使用command substitution语法,否则它需要一个值。

如您所述,您不应该使用cd更改目录 - 您可以将该目录用作ls的参数。此外,wc命令默认返回行数,单词和字节数,并且在表达式中只需要第一个,因此您应该添加参数wc -l

除此之外,您需要决定是否要包含隐藏文件并使用ls -A <dir> | wc -l-Als打印包含隐藏文件的所有文件,但不包括默认...

最后在条件子句中使用double parentheses arithmetical comparison

if (( $(ls -A reports_dir | wc -l) > $MAXIMUM_REPORTS )); then
    echo hello, but read the comment below
fi

话虽如此,上述配方在大多数情况下都适用,但mklement0's answer包含 正确的解决方案。

答案 2 :(得分:1)

这是另一个,cd到一个给定的目录,得到与$ MAXIMUM_REPORTS比较的计数并从那里拿走它。通过两个测试用例。

 [za-  tools]$ MAXIMUM_REPORTS=2; 
     mydir=font-awesome-4.3.0/ ; 
     if [[ $(cd $mydir && ls -1 $@ | wc -l)  -gt $MAXIMUM_REPORTS ]]; then 
        echo "hello" ;
     else echo "byeee" ; fi

输出:     喂

[za tools]$ MAXIMUM_REPORTS=18;
  mydir=font-awesome-4.3.0/ ;
  if [[ $(cd $mydir && ls -1 $@ | wc -l)  -gt $MAXIMUM_REPORTS ]]; then 
     echo "hello" ; 
  else echo "byeee" ; 
fi

输出:     byeee

OR:

file_count=$(ls $mydir 2>/dev/null | wc -l) ; 
if [ $file_count -gt $MAXIMUM_REPORTS ]; then echo "hello" ; else echo "byee" ; fi

模拟wc -l with sed

count=$(ls $mydir 2>/dev/null | sed -n '$=' ) ;
if [ $count -gt $MAXIMUM_REPORTS ]; then echo "$count greater then  $MAXIMUM_REPORTS" ; 
else echo "$count less $MAXIMUM_REPORTS" ; fi