Command-Line
使用普通家居用品設置兩個換行符終止列表的減法/通用黑名單
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)
如果您的列表已排序,您可以使用它
comm -23
來獲取第一個列表的唯一元素。如果不是,您可以使用grep
likefind -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 \;