我需要比较2个目录中的文件,并且能够告诉在Bash中每个文件集保持相同的时间有多长

我需要比较2个目录中的文件,并且能够告诉在Bash中每个文件集保持相同的时间有多长,bash,comparison,Bash,Comparison,基本上,我在不同的目录中有一组.csv文件的两个副本。一份是今天的数据,另一份是昨天的数据。我的脚本使备份每天只运行一次,所以这就是我需要运行备份的频率。我想做的是比较它们,看看文件是否相同,如果一组文件已经相同了14天,那么发送一封电子邮件通知,通知我自己和我的同事某个文件没有更改 我已经把比较部分记下来了: diff-sq DIR_1 DIR_2 | sort>comparison_results.txt 但是,现在我想读取文件,并为每一行设置一个计数器,这样我就可以知道有多少天,每组文件都

基本上,我在不同的目录中有一组.csv文件的两个副本。一份是今天的数据,另一份是昨天的数据。我的脚本使备份每天只运行一次,所以这就是我需要运行备份的频率。我想做的是比较它们,看看文件是否相同,如果一组文件已经相同了14天,那么发送一封电子邮件通知,通知我自己和我的同事某个文件没有更改

我已经把比较部分记下来了:

diff-sq DIR_1 DIR_2 | sort>comparison_results.txt

但是,现在我想读取文件,并为每一行设置一个计数器,这样我就可以知道有多少天,每组文件都是相同的,输出在不同的列中

理想情况下,这3列应该是$name_of|u file |文件是否相同?|他们有多少天是一样的

我已经开始了一个while循环来阅读每一行,但我不确定如何进行:

读行时;做

    counter=0
    if [[ $line == *"not identical"* ]]
    then
        $something
    else
       (( counter += 1 ))
        $something_else
    done < comparison_results.txt
计数器=0
如果[[$line==*“不相同”*]]
然后
美元左右
其他的
((计数器+=1))
$还有别的吗
完成
如有必要,我可以将所有这些输出写入一个文件,然后读取该文件,如果计数器列有14秒或更高,则发送电子邮件通知


基本上,我的问题是如何阅读每一行并将其发送到一个包含3列的文件中,如果其中任何一个文件已经相同了14天或更长时间,则发送电子邮件通知?

这里是一个用于此目的的函数的大致草案。请注意,我只写了超过
minAge
秒的相同文件的名称(以
eval
-安全引用的形式)——发送电子邮件是读者的练习

findConsistentlyIdenticalFiles() {
  local dirA=$1 dirB=$2 storeLoc=$3 minAge=$4
  local fnA fnB fnStore fn currentTime storedTime

  mkdir -p -- "$storeLoc" || return

  # in very new bash, faster alternative is: printf -v currentTime '%(%s)T' -1
  # ...the following command using date is the older/slower/compatible alternative:
  currentTime=$(date +%s)

  # for each file in dirA...
  while IFS= read -r -d '' fnA; do

    # strip the directory name...
    fn="${fnA#$dirA}"; fn="${fn#/}"

    # and calculate the name of a corresponding file in dirB
    fnB=${dirB}/${fn}

    # if a file in dirA doesn't exist in dirB, or the dirB copy differs, clear our flag
    if [[ ! -e $fnB ]] || ! cmp -s "$fnA" "$fnB"; then
      rm -f -- "$storeLoc/$fn"
      continue
    fi

    fnStore=$storeLoc/$fn
    if [[ -e $fnStore ]]; then
      # if we already have a marker, check whether it's over minAge seconds old
      storedTime=$(<"$fnStore")
      if (( storedTime < currentTime - minAge )); then
        printf '%q\n' "$fn"
      fi
    else
      # whereas if we don't have a marker, populate it with the current time
      mkdir -p -- "${fnStore%/*}"
      printf '%s\n' "$currentTime" >"$storeLoc/$fn"
    fi
  done < <(find "$dirA" -type f -print0)

  # ...also, prune any store contents that don't have corresponding dirA contents
  while IFS= read -r -d '' fnStore; do
    fn="${fnStore#$storeLoc}"; fn="${fn#/}"
    [[ -e $dirA/$fn ]] || rm -f -- "$fnStore"
  done < <(find "$storeLoc" -type f -print0)
}
显然,您可以使用更少的秒数来轻松测试逻辑(
60
查找最后一分钟未修改的相同文件,
5
查找最后5秒的相同文件,等等)


一些注意事项:

  • 使用
    find-print0
    发出一个NUL分隔的文件名列表,并且
    IFS=read-r-d”filename
    从这样一个NUL分隔的列表中读取一个名称。即使使用非常不寻常甚至恶意的名称,也可以保证正确解析此格式—带有换行符的名称,包含类似
    diff-sq
    output的字符串的名称,等等。请参阅和

  • <…但是如果你有一个实际的问题,我建议你试着把它提取出来,让它更清楚。另外,特别是个人,顺便说一下,我会考虑在时间段中跟踪一个时间戳,这是第一次观察到两个文件是相同的,并且只是检查当时间戳大于(14×3600)秒之前的情况。这样你就不用处理计数器了,你的脚本可以在同一天内重新运行很多次,而不会破坏逻辑(类似地,跳过一天也不会破坏逻辑,等等)。我编辑了这篇文章来帮助澄清这个问题。我只需要脚本一天运行一次,所以我不确定是否需要时间戳。当然,除非这比柜台更容易处理。从操作角度来看,当然更容易处理。如果您有一个停机或停机窗口,并且您的系统当天错过了它的cronjob,那么您不希望所有的计数都被取消。如果您修复了一个bug,并且希望在修复该bug的情况下重新运行,那么您不希望事情增加两次。作为一个从事这一行业有一段时间的人来说,从减少头痛的角度来看,使脚本幂等通常是一个很好的实践。我会用Qt编写它,因为它有更多更高级的工具,可以用来快速、轻松地编写解决方案
    QDirIterator
    QBuffer
    QTextStream
    QSqlite
    QFileInfo
    是解决此问题的一些工具。。但是如果你的系统已经安装了Qt
    findConsistentlyIdenticalFiles dirA dirB .cmptimes "$(( 3600 * 14 ))"