我在几个月前的外部硬盘驱动器上有一个文件服务器备份,用于从那时起就出现故障的文件服务器。大部分数据已恢复到此后一直使用的临时文件服务器上,但存在一些不一致之处。
我将安装外部并将其与当前数据进行 rsync,但首先我需要建立已在较新副本上更新的文件。
我可以做 diff -r -q /old/ /new/ 来获得这个,我试图更好地编写脚本,所以我试图编写一些东西,每当 diff 返回差异时,将旧文件重命名为 filename.old 。
因此,经过检查后,我无法找到diff仅输出文件名差异的选项,因此我们将仅使用 diff 输出的内容。
如果diff找到不同的文件,则输出如下所示:
Files old/file and new/file differ
Run Code Online (Sandbox Code Playgroud)
由于 bash 脚本要做的就是重命名旧目录中已更改的文件,因此我们希望old/file从此输出中提取内容。让我们首先只显示类似的行Files...differ(因为可能会生成其他行):
diff -rq old/ new/ | grep "^Files.*differ$"
Run Code Online (Sandbox Code Playgroud)
现在你只会得到像前面显示的那样的线条。下一步是获取文件名。您可以awk通过添加类似awk '{print $2}'另一个管道的内容来完成此操作,但如果文件名本身包含空格,awk 会将其分解为两个单独的字符串。我们将使用 sed 来代替:
diff -rq old/ new/ | grep "^Files.*differ$" | sed 's/^Files \(.*\) and .* differ$/\1/'
Run Code Online (Sandbox Code Playgroud)
现在这将生成旧目录中已更改的文件列表。使用简单的 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
Run Code Online (Sandbox Code Playgroud)
就是这样!
编辑:实际上,这还不是全部。这个循环在带有空格的文件上仍然失败,所以让我们稍微处理一下。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
Run Code Online (Sandbox Code Playgroud)
这会暂时将 bash 的默认分隔符 ( $IFS) 替换为换行符,并在循环完成后将其放回原处,这样就不会被空格分割。
| 归档时间: |
|
| 查看次数: |
10511 次 |
| 最近记录: |