使用常见的家居用品设置两个换行符终止列表的负值/通用黑名单

使用常见的家居用品设置两个换行符终止列表的负值/通用黑名单

cp -r最近,当我用完接收驱动器的空间时,我正在使用 备份目录树。我必须继续备份,但备份到不同的目的地。通常,要恢复cp命令,您会要求cp仅复制不在目标中的文件。你可以在这里看到问题。

这是我的解决方案:

  1. 搞砸了。

    # cp -rv sourcedir destdir
    error: no space left on device.
    
  2. 列出所有已成功复制的文件。

    # cd destdir
    # find . >/tmp/alreadycopied
    
  3. 编写一个脚本,可以接受任何列表 A 和一个黑名单 B,并返回一个新列表 C = B \ A,其中包含 A 中不在 B 中的每个元素。我将其称为 setminus。***generate list A*** | setminus listB将 C 返回到标准输出。

  4. 使用 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 \;

相关内容