如何find更改的文件?

我想find在这篇文章底部的testing案例中改变的文件的文件名。

它输出

before d41d8cd98f00b204e9800998ecf8427e FFF/c.txt d41d8cd98f00b204e9800998ecf8427e FFF/a.txt d41d8cd98f00b204e9800998ecf8427e FFF/b.txt after d41d8cd98f00b204e9800998ecf8427e FFF/c.txt d41d8cd98f00b204e9800998ecf8427e FFF/d.txt d8e8fca2dc0f896fd7cb4cb0031ba249 FFF/b.txt 

如何获取已更改的文件的文件名?

在这种情况下, a.txt已经被删除, d.txt被添加,而b.txt已经被改变了md5sum。

 #!/bin/bash mkdir -p FFF touch FFF/a.txt rm -f FFF/b.txt touch FFF/b.txt touch FFF/c.txt rm -f FFF/d.txt echo "before" find FFF -name "*.txt" -exec md5sum '{}' \; echo "" # makes some changes that I want to catch rm -f FFF/a.txt echo "test" > FFF/b.txt touch FFF/d.txt echo "after" find FFF -name "*.txt" -exec md5sum '{}' \; 

有几个选项可以找到自从给定时间点以来发现的文件。 例如,您可以在脚本的起始处touch一个临时文件,然后运行find -newer tmpfile来查找自您touch该临时文件以来已修改的所有文件。

识别在特定状态之间通过哈希(在目录结构中存在)而改变的文件本质上是版本控制系统git所做的,那么为什么不使用它呢? 以下是您的脚本的一个小的修改,它添加了以下步骤:

  1. 将当前目录初始化为git存储库的第一步。
  2. 在创建第一组文件之后,它将从目录的当前状态创建一个提交。
  3. 在接下来的一组修改之后,它创建第二个提交来记录目录的修改状态。
  4. 最后,使用git diff来显示这两个提交之间的变化。

修改后的脚本如下所示:

 #!/bin/bash # Initialize the current directory as a git repository: git init mkdir -p FFF touch FFF/a.txt rm -f FFF/b.txt touch FFF/b.txt touch FFF/c.txt rm -f FFF/d.txt echo "before" find FFF -name "*.txt" -exec md5sum '{}' \; echo "" # Record the state of the directory as a new commit: git add -A . git commit -m "Initial state" # makes some changes that I want to catch rm -f FFF/a.txt echo "test" > FFF/b.txt touch FFF/d.txt echo "after" find FFF -name "*.txt" -exec md5sum '{}' \; # Record the modified state of the directory as a second commit: git add -A . git commit -m "New state" # Output the difference between those two commits: git diff --name-only HEAD^ HEAD 

该脚本的输出是:

 Initialized empty Git repository in /home/mark/tmp/foobar/.git/ before d41d8cd98f00b204e9800998ecf8427e FFF/b.txt d41d8cd98f00b204e9800998ecf8427e FFF/c.txt d41d8cd98f00b204e9800998ecf8427e FFF/a.txt [master (root-commit) 8a6d1d9] Initial state 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 FFF/a.txt create mode 100644 FFF/b.txt create mode 100644 FFF/c.txt after d41d8cd98f00b204e9800998ecf8427e FFF/d.txt d8e8fca2dc0f896fd7cb4cb0031ba249 FFF/b.txt d41d8cd98f00b204e9800998ecf8427e FFF/c.txt [master 810b0f5] New state 2 files changed, 1 insertions(+), 0 deletions(-) rename FFF/{a.txt => d.txt} (100%) FFF/a.txt FFF/b.txt FFF/d.txt 

最后3行是git diff命令的输出。

如果将两个find命令的输出存储到临时文件中,则可以对它们运行diff来找出已更改的文件。 示例输出将是:

 [me@home]$ diff -u ori.temp new.temp | tail -n+4 | grep "^[-+]" | sort -k2 -d41d8cd98f00b204e9800998ecf8427e FFF/a.txt -d41d8cd98f00b204e9800998ecf8427e FFF/b.txt +d41d8cd98f00b204e9800998ecf8427e FFF/d.txt +d8e8fca2dc0f896fd7cb4cb0031ba249 FFF/b.txt 

您应该能够解析该输出以确定更改的文件。 第二列给你的文件名称。 以-开始的行是删除(除非相应的+存在,这意味着它是一个编辑),而以+开头的行是增加。

sort -k2按第二列对输出进行sort -k2 ,以便更容易地找到编辑(文件的重复出现)。


解析diff的输出可以用一些awk甚至纯粹的bash轻松完成。 不幸的是,我的bash / awk-fu没有达到标准,所以这里是我对你的脚本的看法,它使用了一些Python。

 #!/bin/bash # set up initial state mkdir -p FFF && touch FFF/a.txt && rm -f FFF/b.txt touch FFF/b.txt FFF/c.txt && rm -f FFF/d.txt # capture current state TMP_ORI="$RANDOM.ori.tmp" find FFF -name "*.txt" -exec md5sum '{}' \; > $TMP_ORI # makes some changes that I want to catch rm -f FFF/a.txt && echo "test" > FFF/b.txt && touch FFF/d.txt # capture new state TMP_NEW="$RANDOM.new.tmp" find FFF -name "*.txt" -exec md5sum '{}' \; > $TMP_NEW # run diff and parse output diff -u $TMP_ORI $TMP_NEW | tail -n+4 | grep "^[-+]" | python -c ' import fileinput modes = {"+" : "added", "-" : "removed" } visited = {} for line in fileinput.input(): # for each line from stdin checksum, file = line.split() # split the columns if file in visited: visited[file] = "modified" # file appeared before else: visited[file] = modes[checksum[0]] # map "+/-" to "added/removed" for file, mode in visited.iteritems(): # print results print "%s\t%s" % (file, mode) ' rm $TMP_ORI $TMP_NEW # delete temp files 

运行这个脚本将会得到如下输出:

 [me@home] ./sandras_script.sh FFF/d.txt added FFF/a.txt removed FFF/b.txt modified 

好的,你的设置是什么?

  • 你是比较两个目录,并需要知道每个目录已更改的文件? 如果是这样, diff -R会告诉你在涉及的目录中添加,删除和修改了什么。 您可能必须在Solaris上使用diffdirdirdiff
  • 您正在寻找在特定日期之后修改的文件吗? 你可以使用find $dir -mtime 。 这将显示时间戳比-mtime更新(或更早)的文件。

例如:

 $ find $dir -mtime +3 

将会发现三天以前的文件:

 $ find $dir -mtime -3 

会发现三天以下的文件。 有些系统也有-mmin检查分钟。

如果你正在寻找一些随机的瞬间变化,那么我建议你看看使用版本控制系统。 一个好的版本控制系统将给你灵活性,而不必重新发明轮子。 一个命令(如svn log -rPREV:HEAD -v )可以为您提供所需的一切。

两个最流行的版本控制系统是Subversion和Git 。 我发现Subversion更易于使用和设置,但是如果您必须与其他人共享您的代码并且没有中央服务器,那么Git会更好。 Baazar有一个很好的界面,也相当简单。 我刚刚开始玩。

另一种方法是使用文件系统监视器,如inotifydnotifyfamgamin 。 例子:

 inotifywait -m /home/david dnotify -all -r /home/david 

添加选项以执行某些命令或将其输出传送到读取/处理循环。