一般的な家庭用品を使用して2つの改行終了リストを設定するためのネガティブ/ユニバーサルブラックリスト

一般的な家庭用品を使用して2つの改行終了リストを設定するためのネガティブ/ユニバーサルブラックリスト

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

おすすめ記事