일반적인 가정 용품을 사용하여 두 개의 개행 종료 목록을 설정하기 위한 네거티브/범용 블랙리스트

일반적인 가정 용품을 사용하여 두 개의 개행 종료 목록을 설정하기 위한 네거티브/범용 블랙리스트

cp -r최근에 수신 드라이브의 공간이 부족해 백업 디렉터리 트리를 사용하고 있었습니다. 계속 백업해야 하는데 다른 대상으로 백업해야 합니다. 일반적으로 명령을 복원하려면 대상에 없는 파일만 복사하도록 cp요청합니다 . cp여기서 문제를 볼 수 있습니다.

이것이 내 해결책입니다.

  1. 망했다.

    # cp -rv sourcedir destdir
    error: no space left on device.
    
  2. 성공적으로 복사된 모든 파일을 나열합니다.

    # cd destdir
    # find . >/tmp/alreadycopied
    
  3. 목록 A와 블랙리스트 B를 가져와 B에 없는 A의 모든 요소를 ​​포함하는 새 목록 C = B \ A를 반환하는 스크립트를 작성하세요. 나는 그것을 세트마이너스라고 부른다. ***generate list A*** | setminus listBC를 표준 출력으로 반환합니다.

  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 \;

관련 정보