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

bash:计算文件数并进行比较时出错,bash,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: ` i

我不熟悉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放入目录,因为它多次尝试
cd
,导致错误。

解释了OP方法的问题,并提供了基于
ls
的有效解决方案

因为在这种情况下只需要计算文件,所以使用
ls…|wc-l应按预期工作;但是,通常最好在Bash中使用路径名扩展(globbing):

  • Globbing可以安全地用于收集数组中的文件名,并驱动
    for
    循环。
    • 使用
      $(ls…)
      ,这两种方法都不可行-请参阅
  • Globbing是Bash的一个内部特性,因此比使用外部实用程序
    ls
    更有效
以下解决方案演示了如何使用路径名扩展(globbing)来替代
ls

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

  • shopt-s nullglob
    确保在目录为空时不返回任何内容
  • set--reports\u dir/*
    将位置参数(
    $1
    ,…)设置为路径名扩展的结果
  • $#
    返回设置参数的计数,在本例中,它反映了文件的计数
解释OP方法的问题,并提供基于
ls
的有效解决方案

因为在这种情况下只需要计算文件,所以使用
ls…|wc-l应按预期工作;但是,通常最好在Bash中使用路径名扩展(globbing):

  • Globbing可以安全地用于收集数组中的文件名,并驱动
    for
    循环。
    • 使用
      $(ls…)
      ,这两种方法都不可行-请参阅
  • Globbing是Bash的一个内部特性,因此比使用外部实用程序
    ls
    更有效
以下解决方案演示了如何使用路径名扩展(globbing)来替代
ls

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

  • shopt-s nullglob
    确保在目录为空时不返回任何内容
  • set--reports\u dir/*
    将位置参数(
    $1
    ,…)设置为路径名扩展的结果
  • $#
    返回设置参数的计数,在本例中,它反映了文件的计数

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

正如您所指出的,您不应该使用
cd
更改目录-您可以使用目录作为
ls
的参数。另外,默认情况下,
wc
命令返回行数、字数和字节数的计数,并且在表达式中只需要第一个,因此应该添加一个参数
wc-l

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

最后在条件子句中使用for:

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

话虽如此,上述方法在大多数情况下都有效,但包含正确的解决方案。

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

正如您所指出的,您不应该使用
cd
更改目录-您可以使用目录作为
ls
的参数。另外,默认情况下,
wc
命令返回行数、字数和字节数的计数,并且在表达式中只需要第一个,因此应该添加一个参数
wc-l

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

最后在条件子句中使用for:

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

话虽如此,上述配方在大多数情况下都有效,但包含正确的解决方案。

这里还有另一个,将cd放入给定目录,将计数与$MAXIMUM_报告进行比较,然后从中获取。通过两个测试用例

 [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
产出: 拜伊

或:

用sed模拟
wc-l

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

这里是另一个,将cd放入给定的目录中,获取计数并与$MAXIMUM_报告进行比较,然后从那里获取它。通过两个测试用例

 [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
产出: 拜伊

或:

用sed模拟
wc-l

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

“wc-gt$MAXIMUM_REPORTS”的作用是什么。。。。。该命令的整个部分是(cd reports_dir/&&ls)|wc。它会转到该目录并打印文件数。“wc-gt$MAXIMUM_REPORTS”做什么。。。。。该命令的整个部分是(cd reports_dir/&&ls)|wc。它会转到那个目录并打印文件数。我更喜欢这个答案,因为它更容易理解并且适用于大多数情况。我在另一组脚本中使用这个脚本,所以我只是查看“hello”输出以检查它是否正确