
我遇到以下問題。我有一個目錄結構,想要刪除名為 的目錄中的所有內容Caches
。除所有名為 的目錄外,所有內容都應刪除Snapshots
。我不知道如何做到這一點尋找或我知道的任何其他命令。
我問的原因是:在 iOS 上,每個應用程式都有自己的 Caches 目錄。這些有時無法正確清除,具體取決於應用程式。有了這個答案的解決方案,當裝置的驅動器安裝在另一台電腦上時,例如使用 FUSE (iExplorer),人們將能夠清除 iOS 上的緩存,從而優化磁碟空間。
這是我到目前為止所擁有的:
find . 2>/dev/null -type d -name "Caches" -maxdepth 3 -print
這會傳回類似以下內容的內容:
./Library/Caches
當我執行 a 時,ls ./Library/Caches
我會看到所有內容和Snapshots
目錄,我想排除它們,因為最終我想要-delete
除此之外的所有內容。
我想要這樣的東西:
Before: After:
. .
├── a ├── a
│ ├── a │ ├── a
│ └── Caches │ └── Caches
│ ├── a │ └── a
│ │ └── Snapshots │ └── Snapshots
│ │ └── a │ └── a
│ ├── b └── b
│ │ └── a └── c
│ └── c
└── b
├── c
└── Caches
├── a
│ └── foo
│ └── a
└── b
└── a
答案1
我對問題的措辭有點困惑。如果您想要刪除目錄中./Library/Caches
除名為 的單一資料夾之外的所有內容Snapshots
,則無需使用find
.在 中bash
,shell glob 是最簡單的方法:
shopt -s extglob # probably already enabled
echo Library/Caches/!(Snapshots)
如果這會列印您要刪除的所有檔案/目錄,則替換echo
為rm -f --
.
如果您想要保留Snapshots
下面的目錄樹的不同層級的多個目錄,那麼使用 GNU您可以執行以下操作:./Library/Caches
find
find Library/Caches ! -path '*Snapshots*'
這應該列印所有文件/目錄,不包括Snapshots
路徑中的文件/目錄。它將包含包含目錄(或其子目錄包含)的目錄Snapshots
,但find ... -delete
不會刪除這些目錄,而是列印錯誤,指出它們不為空。一旦你感到高興,就添加-delete
到最後。
需要注意的是,這將留下任何文件命名Snapshots
完好。如果這是一個問題,請改為:
find Library/Caches \( ! -path '*Snapshots*' -o -type f -name Snapshots \)
高興的時候再補充-delete
。
答案2
find . -depth -print0 | perl -0lne '
if ("$_/" =~ m{/Caches(/.*)}s && $1 !~ m{/Snapshots/}) {rmdir $_ or unlink $_}'
如果你find
不支持-print0
,你可以用 取代它-exec printf '%s\0' {} +
。
這個想法是列印以 NUL 結尾的檔案清單(因為 0 是唯一不能出現在檔案路徑中的位元組),並使用perl
's-n
和-0
選項為每個檔案名稱運行一些程式碼($_
設定為檔案名稱) )。
使用 時-depth
,檔案將在其父目錄之前列印。如果檔案或目錄depth
的路徑/Caches/
後面不包含/Snapshosts/
.
答案3
我不是find
巫師,所以我不想說你不能用 來做到這一點find
,但我確實知道可以用幾行 來完成bash
。鑑於我正確理解您的目錄結構:
#!/bin/bash
for i in Library/Caches/*; do
if [[ -d "$i" ]]; then
[[ "$i" =~ "Snapshots" ]] || echo "rm-ing $i" # change to rm -rf "$i" to use
fi
done
該for
語句傳回 中的每個項目Library/Caches/
。該if [[ -d "$i" ]]
語句檢查每個項目是否為目錄,如果是,請檢查它的名稱以查看它是否包含“Snapshots” [[ "$i" =~ "Snapshots" ]]
。因為沒有運算符可以否定正規表示式匹配,例如!=~
,所以我過去常常在上一個命令不成功時||
執行rm
,例如目錄名稱不包含快照。
這將在任何使用的現代系統上運行bash
,但它必須有bash
。另外,您可能需要嘗試目錄結構,但這應該適合您。
答案4
第一部分:找到名為caches的目錄並對它們執行一些操作
find . -name Caches -type d -exec … \;
第二部分:遍歷快取目錄,並刪除所有內容,但保留Snapshots
子目錄及其內容(以及通往它們的路徑)。進行深度優先遍歷,這樣目錄一旦變空就可以刪除。
find /path/to/Caches -depth -name Snapshots -type d -prune \
-o \( -type d -empty -o ! -type d \) -delete
現在將它們組合在一起。
find . -name Caches -type d -exec
find {} -depth -name Snapshots -type d -prune \
-o \( -type d -empty -o ! -type d \) -delete