如何使计数器变量对于文件的每一行都是唯一的

如何使计数器变量对于文件的每一行都是唯一的

所以我有 2 个具有相同文件的目录,除了目录 a 是今天的数据,目录 b 是昨天的数据。我想要做的是比较文件并将结果输出到 3 列中,这将是文件名、文件是否相同以及文件相同的天数。

到目前为止我所拥有的是:

ls ./dropzone_current > files.txt

is_identical=false


filename="files.txt"
while read -r line
do
    name="$line"
    declare -i counter 
    diff -qs ./dropzone_current/$name ./dropzone_backup/$name
    if [ $? -ne 0 ]
    then
    is_identical=false
    counter=0
    printf '%s\t%s\t%s\n' "$name" "$is_identical" "$counter" >> test.txt

    else
    counter=$((counter + 1))
    is_identical=true
    printf '%s\t%s\t%s\n' "$name" "$is_identical" "$counter" >> test.txt
    fi


done < "$filename"

本质上,除了柜台之外,一切都正常。我需要计数器对于正在比较的每个文件名都是唯一的,然后在每次运行脚本时更新(每天一次),但我无法弄清楚如何做到这一点。

答案1

根据对我的其他答案和您的问题的评论,听起来您真正正在寻找的是一种跟踪一组文件更改的方法。这通常称为版本(或修订)控制。通常安装在系统上的一种常见引擎是git

为了实现这一点,选择一个位置来存储我们称之为“存储库”的位置,它将存储文件的副本并跟踪其中的所有更改。我们将这个位置称为/path/to/repository。创建该目录,然后运行命令git init。这将设置存储库。将文件复制到目录中,我们现在将当前状态“提交”到存储库:

git add *
git commit -m "Initial commit of files"

然后,您可以简单地查看交付位置并根据需要更新存储库:

#!/bin/bash
repo='/path/to/repository'
dropbox='/path/to/delivery/'

cd $repo
for file in *; do
    if ! diff "${repo}/$file" "${dropbox}/$file"; then
        cp -p "${dropbox}/$file" ${repo}/
        git add "$file"
    fi
done
git commit -m "Update for $(date)"

这是一个快速而肮脏的脚本,不能很好地处理名称中带有空格的文件,或者从提要中添加或删除的文件,但它是一个起点。

答案2

如果您希望它在多次运行脚本时保持状态,则需要将文件拖放到磁盘或其他一些非易失性介质上,脚本将在启动时读取该文件以进行初始化,并在退出时写入以供将来参考:

#!/bin/bash
dropfile='/path/to/your/counterfile'
if [[ -r "$dropfile" ]]; then
    counter=$(cat "$dropfile" )
else
    counter=0
fi
trap 'echo $counter > "$dropfile"' EXIT

echo "This script has run $counter times."
counter=$((counter+1))

答案3

我会建立一个版本控制系统。例如,使用mercurial,hg init在存储文件的目录中。然后每天一次(可能作为cron新文件放置在那里之后的一项工作),hg addremove并且hg commit.

然后要运行报告,您可以循环每个文件 ( for filename in dropzone/*; do) 并获取最后提交的时间戳,例如hg log -l 1 --template "{date(date, '%s')}\n" "$filename"。将为%s您提供 UNIX 秒时间戳;您可以使用 获取当前值$(date +%s),减去该值,然后将其大致转换为天数。

任何 VCS(svngit等)都适合您,因此只需使用您喜欢的即可。

相关内容