发现意外的“。”,使wc -l列出比预期更多的内容

时间:2015-12-23 21:26:18

标签: shell unix scripting find

我正在尝试使用更新的命令,如下所示:

touch $HOME/mark.start -d "$d1"
touch $HOME/mark.end -d "$d2"
SF=$HOME/mark.start
EF=$HOME/mark.end
find . -newer $SF ! -newer $EF

但是这给了我这样的输出:

.
./File5

并将其计为2个文件,但该目录只有1个文件,即File5。为什么会发生这种情况以及如何解决?

更新

我实际上是在尝试运行以下脚本:

#!/bin/bash
check_dir () {
  d1=$2
  d2=$((d1+1))
  f1=`mktemp`
  f2=`mktemp`
  touch -d $d1 $f1
  touch -d $d2 $f2
  n=$(find $1 \( -name "*$d1*" \) -o \( -newer $f1 ! -newer $f2 \) | wc -l)
  if [ $n != $3 ]; then echo $1 "=" $n ; fi
  rm -f $f1 $f2
}

检查目录是否具有格式为YYYMMDD的特定日期或其最后修改时间是最后1天的文件。

check_dir ./dir1 20151215 4
check_dir ./dir2 20151215 3

在dir1中应该有4个这样的文件,如果不是真的那么它将打印那里的实际文件数。

因此,当目录只有名称中包含日期的文件时,它会检查它们没问题,但是当它用较新的检查时,它总是提供1个额外的文件(在目录中甚至没有)。为什么会这样?

1 个答案:

答案 0 :(得分:0)

该问题询问为什么.的结果中会有额外的find,即使没有该名称的文件或目录也存在。答案很简单:. 始终存在,即使它被隐藏了。使用ls -a显示隐藏的内容,您就会看到它的存在。

您现有的find命令不会将目标目录本身 - . - 从合法结果中豁免,这就是您获得的结果超出预期的原因

添加以下过滤器:

-mindepth 1  # only include content **under** the file or directory specified

...或者,如果您只想计算文件,请使用...

-type f      # only include regular files

顺便说一下,假设GNU发现,这一切都可以提高效率:

check_dir() {
  local d1 d2 # otherwise these variables leak into global scope
  d1=$2
  d2=$(gdate -d "+ 1 day $d1" '+%Y%m%d') # assuming GNU date is installed as gdate
  n=$(find "$1" -mindepth 1 \
                -name "*${d1}*" -o \
                '(' -newermt "$d1" '!' -newermt "$d2" ')' \
                -printf '\n' | wc -l)
  if (( n != $3 )); then
    echo "$1 = $n"
  fi
}