簡體   English   中英

刪除除兩個特定目錄之外的所有文件/目錄

[英]Delete all files/directories except two specific directories

所以,似乎有一些問題要求刪除匹配某些情況的文件/目錄,但我正在尋找完全相反的:刪除與我提供的示例不匹配的文件夾中的所有內容。

例如,這是一個示例目錄樹:

.
|-- coke
|   |-- diet
|   |-- regular
|   `-- vanilla
|-- icecream
|   |-- chocolate
|   |-- cookiedough
|   |-- cupcake
|   |   |-- file1.txt
|   |   |-- file2.txt
|   |   |-- file3.txt
|   |   |-- file4.txt
|   |   `-- file5.txt
|   `-- vanilla
|-- lol.txt
|-- mtndew
|   |-- classic
|   |-- codered
|   |-- livewire
|   |   |-- file1.txt
|   |   |-- file2.txt
|   |   |-- file3.txt
|   |   |-- file4.txt
|   |   `-- file5.txt
|   `-- throwback
`-- pepsi
    |-- blue
    |-- classic
    |-- diet
    `-- throwback

我想刪除test / icecream / cupcake /和test / mtndew / livewire /中的文件。 其他一切都可以,包括目錄結構。 那么,我怎樣才能做到這一點? 我不介意的語言:bash或python。

此命令將只在原始目錄中保留所需的文件:

find test \( ! -path "test/mtndew/livewire/*" ! -path "test/icecream/cupcake/*" \) -delete

不需要cpio。 它適用於Ubuntu,Debian 5和Mac OS X.

在Linux上,它將報告它無法刪除非空目錄,這正是所需的結果。 在Mac OS X上,它會悄悄地做正確的事情。

“除了”之外的一切都是為什么我們有if語句; 以及為什么os.walk的目錄列表是一個可變列表。

for path, dirs, files in os.walk( 'root' ):
    if 'coke' in dirs:
        dirs.remove('coke')
        dirs.remove('pepsi')

find 's -prune ,但讓它適用於特定的路徑( icecream/cupcake/ )而不是特定的目錄( cupcake/ )是很痛苦的。

就個人而言,我只是使用cpio和硬鏈接(以避免必須復制它們)要保留到新樹的目錄中的文件,然后刪除舊的:

find test -path 'test/icecream/cupcake/*' -o -path 'test/mtndew/livewire/*' | cpio -padluv test-keep
rm -rf test

這也將保留您打算保留的目錄的現有目錄結構。

find /path/to/test/ -depth -mindepth 1 \
! -path "/path/to/test/icecream/cupcake/*" \
! -path "/path/to/test/icecream/cupcake" \
! -path "/path/to/test/icecream" \
! -path "/path/to/test/mtndew/livewire/*" \
! -path "/path/to/test/mtndew/livewire" \
! -path "/path/to/test/mtndew"
 -delete -print

編寫所有要保留的路徑有點單調乏味,但這是單獨使用find的唯一方法。

你可以根據Python的os.walk函數做一些事情:

import os
for root, dirs, files in os.walk(top, topdown=False):
    for name in files:
        os.remove(os.path.join(root, name))
    for name in dirs:
        os.rmdir(os.path.join(root, name))

...只是添加一些東西來忽略你感興趣的路徑。

將要保留的內容移動到其他位置,然后刪除剩下的內容。

find

您的命令將類似於:

find $directory \( -prune 'some pattern' \) -delete

解決問題的oneliner:

找 。 | grep -v“test / icecream / cupcake /”| grep -v“test / mtndew / livewire /”| xargs rm -r

刪除,因為它不起作用

如果文件名中包含空格,這可能會讓您遇到麻煩,如果有其他樹匹配模式,它可能會保留更多文件。

一個更好的解決方案:

find . |sed "s/.*/rm '&'/"|grep -v "rm './test/icecream/cupcake/"| grep -v "rm './test/mtndew/livewire/"|sh

沒有經過實際測試,如果它打破了,你可以保留兩個部分。

編輯:由於丹尼斯不僅指出它分成兩部分:-)更正了第二個例子中的拼寫錯誤並刪除了第一個

它適用於我使用兩個步驟查找:首先刪除允許的文件,然后刪除它們的空目錄!

find -x -E ~/Desktop/test -not \( -type d -regex '.*/(cupcake|livewire)/*.*' -prune \) -print0 | xargs -0 ls -1 -dG 

# delete the files first

# Mac OS X 10.4 
find -x -E ~/Desktop/test -not \( -type d -regex '.*/(cupcake|livewire)/*.*' -prune \) -type f -exec /bin/rm -fv '{}' \; 

# Mac OS X 10.5 
find -x -E ~/Desktop/test -not \( -type d -regex '.*/(cupcake|livewire)/*.*' -prune \) -type f -exec /bin/rm -fv '{}' + 

# delete empty directories 
find -x ~/Desktop/test -type d -empty -delete 

像其他人一樣,我使用os.walk和os.path.join構建要刪除的文件列表,使用fnmatch.fnmatch選擇必須包含或排除的文件:

#-------------------------------#
# make list of files to display #
#-------------------------------#
displayList = []
for imageDir in args :
    for root,dirs,files in  os.walk(imageDir) :
        for filename in files :
            pathname = os.path.join( root, filename ) 
            if fnmatch.fnmatch( pathname, options.includePattern ) :
                displayList.append( pathname )


#----# now filter out excluded patterns #----#
try :
    if len(options.excludePattern) > 0 :
        for pattern in options.excludePattern :
            displayList = [pathname for pathname in displayList if not fnmatch.fnmatch( pathname, pattern ) ]
except ( AttributeError, TypeError ) :
    pass

如果fnmatch不夠,可以使用re模塊測試模式。

在我做任何事情之前,我已經構建了文件列表,但您可以在生成文件時處理這些文件。

如果我的選項類實例沒有排除模式,或者它在fnmatch中導致異常,因為它是錯誤的類型。

此方法的局限性在於它首先包含與模式匹配的文件, 然后排除 如果你需要比這更靈活(包括匹配模式a,但不包括模式b,除非模式c ...),那么上面的片段不符合它。 實際上,通過本練習,您將開始了解查找命令語法的原因。 看起來很笨,但事實上它正是這樣做的方式。

但是,如果生成列表,則可以根據所需的包含/排除規則對其進行過濾。

生成列表的一個好處是你可以在繼續刪除之前檢查它。 這有點像'--dryrun'選項。 您可以在python解釋器中以交互方式執行此操作,打印列表以查看其外觀,應用下一個過濾器,查看它是否已刪除太多或太少等等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM