刪除除 1 之外的所有重複圖像文件
我有一個包含很多重複項的圖像文件夾,我想刪除除一個之外的所有重複項。
Google搜尋後,我從這篇文章中發現了這個聰明的腳本,它簡潔地完成了我想要它做的事情:
#!/bin/sh -eu find "${1:-.}" -type f ! -empty -print0 | xargs -0 md5 -r | \ awk '$1 in a{sub("^.{33}","");printf "%s\0",$0}a[$1]+=1{}' | \ xargs -0 rm -v --
不幸的是,當談到 UNIX shell 腳本時,我仍然相當陌生,所以我不確定每個部分的實際命令/標誌在這裡做什麼,所以我無法根據我的特定需求對其進行修改。
據我了解:
find "${1:-.}" -type f ! -empty -print0
- 在目前目錄中搜尋非空文件並列印文件名。(雖然不知道這件作品是什麼"${1:-.}"
意思)
| xargs -0 md5 -r
- 將上面的結果(通過xargs -0
命令?)通過管道傳遞到md5
命令中以獲取每個文件的 md5 雜湊簽名(-r
反轉輸出以使其成為單行?)
awk '$1 in a{sub("^.{33}","");printf "%s\0",$0}a[$1]+=1{}'
- 這就是我迷路的地方..
$1 in a{sub("^.{33}","")
- 將輸入直到第一個空白字元,並將字元串開頭的前 33 個字元替換為空 (sub("^.{33}",""
)printf "%s\0"
- 格式列印整個字元串a{...,$0}
- 我不確定這是做什麼的a[$1]+=1{}
- 也不確定
xargs -0 rm -v --
- 將結果傳遞給rm
命令,通過 列印每個文件名-v
,但我不確定語法--
的用途。當我執行它時,它會像這樣輸出,
./test3.jpg./test2.jpg./test.jpg: No such file or directory
所以一定存在格式問題。我的問題是:
- 可以修改它以刪除除 1 之外的所有文件嗎?
- 有人可以幫助解釋我上面概述的命令/語法含義的差距嗎?
我確信這對於熟悉 UNIX 的人來說可能很容易,但不幸的是,那個人不是我。先感謝您!
對於上下文:我在 macOS BigSur 11 的 ZSH 中執行它。
我將重點關注
awk
-part 這裡:
md5 -r
返回 32 個字元的 md5-sum,然後是文件名。因此,md5-sum 是awk
.$1 in a{...}
表示“如果
$1
(此處:md5-sum)在數組中作為索引找到,a
則執行命令 {…}”。所以a
將用作一個數組,其中 md5 和作為已經看到的索引。請注意,如果此值不存在或為 0,則不會執行命令 - 因此第一次看到 md5-sum 時,不會返回文件名。如果它是任何其他值(包括字元串),則條件為真,並執行命令。sub("^.{33}","");printf "%s\0",$0
將從開頭刪除 33 個字元,即 md5-sum 和後面的空格,然後在末尾使用 NUL 分隔符列印其餘的(原始文件名)。NUL 分隔對於帶有空格的文件很重要。見或中。
-print0
_ 請注意,如果 md5-sum 已經在 array 中,則僅執行此命令,因此不返回第一個匹配項(即僅顯示重複項,然後將其刪除)。man find``-0``man xargs``a
a[$1]+=1{}
“將 1 添加到數組的元素 $1
a
”,$1 是 md5-sum。a
因此,一旦看到 md5-sum ,就會設置此值。它是重複計數器。’{}’ 是空命令。這是必要的,因為awk
如果滿足條件並且沒有給出命令,預設情況下會返回完整記錄。警告
據我所見,該腳本適用於帶有空格的文件,但我認為對於名稱中帶有換行符的文件,它會失敗,因為
awk
沒有將 NUL 設置為記錄分隔符,然後預設為換行符。首先使用BEGIN {RS="\x0"}
inawk
設置它。