cp -r
最近,当我用完接收驱动器的空间时,我正在使用 备份目录树。我必须继续备份,但备份到不同的目的地。通常,要恢复cp
命令,您会要求cp
仅复制不在目标中的文件。你可以在这里看到问题。
这是我的解决方案:
搞砸了。
# cp -rv sourcedir destdir error: no space left on device.
列出所有已成功复制的文件。
# cd destdir # find . >/tmp/alreadycopied
编写一个脚本,可以接受任何列表 A 和一个黑名单 B,并返回一个新列表 C = B \ A,其中包含 A 中不在 B 中的每个元素。我将其称为 setminus。
***generate list A*** | setminus listB
将 C 返回到标准输出。使用 find 和 setminus 将所有剩余文件复制到新目标。
# cd sourcedir # find . -type f | setminus /tmp/alreadycopied | xargs -d '\n' -I file cp -v --parents file overflowdestdir
它起作用了,但我认为这组减去列表的问题是一个足够常见的问题,标准 UNIX 工具必须以某种方式涵盖这个用例,从而使我的脚本变得不必要。你们中有人遇到过这个问题吗?如果有,您是如何解决的?
setminus 脚本:
#!/usr/bin/env python3
# ***generate list*** | setminus blacklist
# Performs a set minus on its inputs and returns the result. Specifically,
# filters a newline-separated list in stdin using blacklist---also a
# newline-separated list. If an element of stdin is found in blacklist, it is
# excluded from the output. Otherwise, the element is returned to stdout. Very
# useful in conjunction with find commands.
from sys import *
try:
blacklistfile = argv[1]
except IndexError:
stderr.write('usage: ***generate list*** | setminus blacklist.\n')
exit(1)
# A dict is used instead of a list to speed up searching. This blacklist could potentially be very large!
blacklist = {}
for line in open(blacklistfile):
blacklist[line] = True
for line in stdin:
inblacklist = False
try:
inblacklist = blacklist[line]
except KeyError:
pass
if not inblacklist:
stdout.write(line)
答案1
如果您的列表已排序,您可以使用它comm -23
来获取第一个列表的唯一元素。如果不是,你可以使用grep
像
find -type f | grep -vFxf /tmp/alreadyCopied
-v
会找到所有没有匹配的行-F
告诉它使用字符串作为固定字符串,而不是模式-x
匹配整行而不是行中任意位置的字符串-f /tmp/alreadyCopied
从给定文件中读取要匹配的行
不过,您必须确保路径匹配,因此如果find
生成,./dir1/file1
则需要与中的字符串相同/tmp/alreadyCopied
但请注意,如果您有一个文件名,这种一般方法将会出现问题\n
。你可能可以find
用类似的东西重做整个事情
find . -type f -exec test ! -f destdir/{} \; -exec cp -v --parents {} overflowdestdir \;