gpt4 book ai didi

bash - 用于递归比较目录的 Shell 脚本

转载 作者:行者123 更新时间:2023-11-29 09:26:47 25 4
gpt4 key购买 nike

我在几个月前的外部硬盘驱动器上有一个文件服务器备份,用于从那以后发生故障的文件服务器。大部分数据已恢复到从那时起一直在使用的临时文件服务器上,但存在一些不一致之处。

我将挂载外部并将其与当前数据同步到它,但首先我需要建立已在较新副本上更新的文件。

我可以做 diff -r -q/old//new/来获得这个,我试图在脚本编写方面做得更好,所以我正在尝试编写一些东西,只要 diff 返回一个,就会将旧文件重命名为 filename.old区别。

最佳答案

所以在检查之后,我无法在 diff 中找到仅输出文件名差异的选项,因此我们将只处理 diff 输出。

如果 diff 找到不同的文件,输出是这样的:

Files old/file and new/file differ

由于您的 bash 脚本所做的只是从旧目录重命名已更改的文件,因此我们希望从此输出中提取 old/file。让我们从仅显示类似 Files...differ 的行开始(因为可能会生成其他行):

diff -rq old/ new/ | grep "^Files.*differ$"

现在您只会得到如前所示的线条。下一步是获取文件名。您可以使用 awk 通过添加类似 awk '{print $2}' 的内容作为另一个管道来执行此操作,但如果文件名本身包含空格,awk 会将其分解为两个单独的字符串。我们将改用 sed:

diff -rq old/ new/ | grep "^Files.*differ$" | sed 's/^Files \(.*\) and .* differ$/\1/'

现在这将生成旧目录中已更改的文件列表。使用简单的 for 循环,您现在可以重命名每个文件:

for old_file in `diff -rq old/ new/ | grep "^Files.*differ$" | sed 's/^Files \(.*\) and .* differ$/\1/'`
do
mv $old_file $old_file.old
done

就是这样!

编辑:实际上,这还不是全部。这个循环在有空格的文件上仍然失败所以让我们稍微处理一下。默认情况下,for 将尝试生成以空格分隔的列表。让我们将其更改为使用换行符:

OLD_IFS=$IFS
# The extra space after is crucial
IFS=\

for old_file in `diff -rq old/ new/ | grep "^Files.*differ$" | sed 's/^Files \(.*\) and .* differ$/\1/'`
do
mv $old_file $old_file.old
done
IFS=$OLD_IFS

这暂时将 bash 的默认分隔符 ($IFS) 替换为换行符,并在循环完成后将其放回原处,这样您就不会被空格分隔。

关于bash - 用于递归比较目录的 Shell 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6765054/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com