題 如何刪除目錄以外的所有文件?


我需要刪除目錄中的所有文件,但不包括其中一些文件。例如,在包含文件的目錄中 a b c ... z,我需要刪除所有除外 u 和 p。是否有捷徑可尋?


119
2018-01-08 12:17


起源


下面的答案要好得多,但您可以將文件保存為只讀,刪除所有文件,然後將其更改回原始權限(只要您不使用rm -f)。您必須知道要恢復的權限,並且您必須知道在此過程中不需要對它們進行寫訪問。這就是其他答案更好的原因。 - Joe
如果你還想刪除運行的隱藏文件 shopt -s dotglob 在跑步之前 rm (...)。


答案:


在這種情況下我做的是鍵入

rm *

然後我按 按Ctrl+X* 至 擴大  * 到所有可見的文件名。

然後我可以從列表中刪除我想保留的兩個文件,最後執行命令行。


108
2018-01-08 12:18



我想這只有文件列表才有效 * 擴展也不會太長。 : - } - Frerich Raabe
Esc後跟*也會擴展“*”。 - slowpoison
@SantoshKumar:這對我來說沒有意義。擴展將始終有效,它不依賴於您之後要使用的命令。 - Der Hochstapler
@OliverSalzburg對不起,這個組合有點令人困惑。我覺得你應該這樣寫 Ctrl + Shift + x + * - Santosh Kumar
@SantoshKumar:但那不是組合。 - Der Hochstapler


rm 除了 u,p 在bash中輸入:

rm !(u|p)

這需要設置以下選項:

shopt -s extglob

看更多: glob - 格雷格的維基


143
2018-01-08 12:34



你必須有'extglobbing'活躍:shopt -s extglob - sparkie
你需要 shopt -s extglob,@ Ashot。此外,它只是文件,而不是目錄,這就是為什麼我刪除了 -rf 命令中的選項。 - slhck
如果您需要排除一個文件 一個選擇 的文件,試試這個: rm !(index).html。這將刪除以“.html”結尾的所有文件,但“index.html”除外。 - mzuther


您可以使用 find

find . ! -name u ! -name p -maxdepth 1 -type f -delete
  • ! 否定下一個表達
  • -name 指定文件名
  • -maxdepth 1 將使查找進程僅指定目錄(find 默認情況下遍歷目錄)
  • -type f 將只處理文件(而不是例如目錄)
  • -delete 將刪除文件

然後,您可以調整查看條件 查找的手冊頁

更新

  • 請記住,表達式元素的順序很重要(請參閱文檔)
  • 首先使用測試您的命令 -print 代替 -delete

    find . ! -name u ! -name p -maxdepth 1 -type f -print
    

68
2018-01-08 12:35



@Dennis謝謝我更新了答案 - Matteo
謂詞順序在這里至關重要。如果放一個 -delete 剛過 . 這將是災難(將刪除CWD中的所有文件) - Michał Šrajer
這可以寫得更緊湊 find . -maxdepth 1 -type f -name '[^up]' -delete - kojiro
@kojiro yes但僅適用於只有一個字母的文件。隨著更複雜的名稱,正則表達式可能是一團糟。 - Matteo
find 是我最好的朋友,特別是當有太多的文件要起來 - Terence Johnson


簡單:

mv 你想要在上層目錄中的文件, rm 目錄然後 mv 他們回來了。


42
2018-01-08 12:22



當然,將它們轉到更高的目錄。盡量不要將它們轉移到你要刪除的子目錄中...... - Konerak
@Konerak: rm 無 -r 不會刪除子目錄。 - reinierpost
這將覆蓋目標目錄中具有相同名稱的文件 - Matteo
我正在低估這一點,因為雖然它可以很方便,但它也是非原子的,可以在短時間內有效地從目錄中刪除所有文件;例如,如果文件在網絡上共享,則這是不可接受的。 - sam hocevar


有點相似 這個答案 但是不需要特殊的選項,據我所知,以下是任何(模糊)/ bin / sh類似shell支持的“古老”功能(例如bash,zsh,ksh等)

rm [^up]

15
2018-01-08 14:22



這適用於1-char文件名。對於更長的名字,sparkie的答案更好。 - glenn jackman
會有什麼問題 rm [^up]*?我經常做類似的事情。 - α CVn
@MichaelKjörling - 這將刪除所有以u或p開頭的文件,而不僅僅是名稱為u和p的文件。我認為OP(@Ashot)意味著a-z和u,p等。象徵性而非字面意思。 - Sudipta Chatterjee
@HobbesofCalvin這會刪除所有文件 不 從u或p開始,而不是從它們開始的那些。 - rjmunro
@rjmunro - 謝謝,錯過了那一個! :) - Sudipta Chatterjee


這樣做沒有找到:

ls | grep -v '(u|p)' | xargs rm

(編輯:“u”和“v”,就像在這裡的其他地方一樣,被用作整個正則表達式的通用版本。顯然你需要小心固定你的正則表達式以避免匹配太多的東西。)

正如其他人所建議的那樣,如果你要做很多事情,你肯定會想要一個劇本。


11
2018-01-09 03:54



grep默認情況下不會處理擴展的regexpt:要么使用 -E 要么 egrep - Matteo
這將排除包含a的任何文件 u 或者a p - Matteo
@Matteo不,不會。 grep沒有grepping文件,它正在grep ls命令的輸出。你在想類似的東西 grep -L (u|p)' * | xargs rm哪裡 -L 表示不包含匹配項的列表文件名。 - rjmunro
哦,你的意思是任何名字包含的文件 u 要么 p,不是任何包含的文件 u 或者a p。那是正確的。您可以使用修復 egrep -v '^(u|p)$' - rjmunro
除了這些比賽,這裡刪除所有內容! ls | grep -v 'vuze\|progs' | xargs rm -rf - Nick


在zsh中:

setopt extended_glob  # probably in your .zshrc

然後

rm ^(u|p)

要么

rm *~(u|p)

即使你有第二個將工作 ^ 在 $histchars 對於歷史替換,當然你可以在之前放置一個任意的glob ~


6
2018-01-09 22:34





GLOBIGNORE採用以冒號分隔的列表

GLOBIGNORE=u:p
rm *

5
2018-01-08 16:32



這不適用於我的shell(GNU bash 4.1.5(1))。 一定要先測試一下比它有害的東西 rm 或者在測試目錄中! - α CVn


回到軟盤時代,我有一個名為“Except”的dos可執行文件,可以暫時將事物移出當前目錄並執行命令,因此您可以說:

除了* .txt del *。*

刪除除文本文件之外的所有內容。

這可能是一個非常簡單的事情,作為一個shell腳本實現,如果這是你可能會做兩次以上的事情似乎是一個好主意。


3
2018-01-08 17:02



它讓我想起了同樣的事情。但是在多任務處理時代暫時離開文件夾可能不是一個好主意:) - Sedat Kapanoglu


 find . -maxdepth 1 ! -name "u" ! -name "p" -type f -exec rm -rf {} \;

這將刪除unix中除u和p之外的所有文件


3
2018-01-08 17:58





對於那些喜歡在完整的正則表達式emacs,posix-awk或posix-extended樣式中指定任意複雜排除模式(跨越所有受影響的文件名)的人(請參閱查找手冊頁)我會推薦這個。它不包括在內 u 和 p 在本例中的當前目錄中。這對於腳本來說可能很方便。

find -regextype posix-awk ! -regex './(u|p)' -print0 | xargs -0 rm -rf

2
2018-01-08 18:16



您需要在表達式之前指定一個目錄(`find.-regextype ...)。 - Matteo
-regextype 只適用於GNU版本 - Matteo
不 - 如果應該使用當前目錄,我的查找版本(debian squeeze)確實不需要表達式之前的顯式目錄 - sparkie
@sparke:這只適用於GNU實現 - Matteo
@sparkie:沒有定義目錄(第一個參數) find 是GNU的擴展 find 命令。這同樣適用 -regextype 選項。此外,您的命令也將刪除子目錄中的文件,而原始問題清楚地詢問目錄中的文件。 - Mikko Rantalainen