排序和復製文件
我是新手,請耐心等待。
我有一個包含數千個文件的目錄。文件名總是以 1 或 2 個字母開頭,並且在下劃線“_”之前有 4 個字元。每個模式的文件數可以不同,下劃線後的文件名部分改變。
樣本:
Parentdir: ->AA01_*.pdf ->AA01_*.html ->AA01_*.txt ... ->ZZ99_*.pdf ->ZZ99_*.html ->ZZ99_*.txt ... ->A001_*.pdf ->A001_*.html ->A001_*.txt ... ->Z999_*.pdf ->Z999_*.html ->Z999_*.txt
我想執行一個命令,該命令將僅使用文件名中的字母創建新目錄,並使用以這些字母開頭的文件填充它們。如果目標目錄中有同名文件(源目錄中的更新文件),我想保留最新的文件。所以:
New dir/files: ->AA AA01_*.pdf AA01_*.html AA01_*.txt ... ->ZZ ZZ99_*.pdf ZZ99_*.html ZZ99_*.txt ... ->A A001_*.pdf A001_*.html A001_*.txt ... ->Z Z999_*.pdf Z999_*.html Z999_*.txt
這可以實現嗎?
謝謝!
循環遍歷文件集。選擇字母前綴。創建目錄(如有必要)並將文件移動到其中。
#!/bin/sh for item in * do if [ -f "$item" ] then prefix="$(echo "$item" | sed 's/[^A-Z].*//')" echo mkdir -p "$prefix" echo mv "$item" "$prefix/" fi done
刪除
echo
前綴mkdir
,mv
當你高興時,它會做你想做的事。
使用perl 實用程序(在某些 linux 發行版上
rename
又名prename
,file-rename
) :perl-rename
rename -n 'if (m/^(\w{1,2}?)(\d{2,}_.*)/) {mkdir $1; $_ = "$1/$1$2"}' *
注意:這僅適用於基於 perl 的重命名實用程序。
rename -V
您可以通過執行(或prename -V
或file-rename -V
或)檢查是否安裝了它perl-rename -V
。如果這提到 perl 或File::Rename
,那麼它是 perl 版本的rename
. 否則,它可能具有完全不同rename
且不兼容的功能和命令行選項。這不適用於 util-linux 的重命名(或任何其他版本的重命名 - 它需要perl 重命名)util-linux
這使用每個匹配文件名的前一個或兩個“單詞”字元(非貪婪匹配)作為目錄,然後創建目錄,並將文件重命名為目錄。“單詞”字元 (
\w
) 定義man perlre
為:“匹配“單詞”字元(字母數字加“_”,加上其他連接符標點字元加 Unicode 標記)”
如果這不是您想要的,您可以使用,例如
[[:alpha:]]{1,2}?
代替\w{1,2}?
任何字母字元或[[:upper:]]{1,2}
僅大寫字元來優化模式。
\d
僅匹配數字。如果您想在下劃線之前允許任何單詞字元,請使用\w
. 或者[[:alnum:]]
,如果您只想允許字母和數字字元,請使用。與整個模式不匹配的文件名(1 或 2 個“單詞”字元,後跟至少兩位數字,後跟下劃線)不受影響。
注意:該
-n
選項使其成為空執行操作。它只會顯示它會做什麼,而不會實際執行。一旦確定它可以滿足您的要求,請刪除-n
(或將其替換-v
為詳細輸出)。例如,給出以下設置腳本:
#!/bin/bash for i in A AA Z9 ZZ ; do for j in {01..10} ; do touch "$i${j}_.txt" done done # anomaly touch A1001_.txt
$ ./setup.sh $ ls A01_.txt A02_.txt A03_.txt A04_.txt A05_.txt A06_.txt A07_.txt A08_.txt A09_.txt A1001_.txt A10_.txt AA01_.txt AA02_.txt AA03_.txt AA04_.txt AA05_.txt AA06_.txt AA07_.txt AA08_.txt AA09_.txt AA10_.txt setup.sh* Z901_.txt Z902_.txt Z903_.txt Z904_.txt Z905_.txt Z906_.txt Z907_.txt Z908_.txt Z909_.txt Z910_.txt ZZ01_.txt ZZ02_.txt ZZ03_.txt ZZ04_.txt ZZ05_.txt ZZ06_.txt ZZ07_.txt ZZ08_.txt ZZ09_.txt ZZ10_.txt
執行 perl 重命名腳本後:
$ rename 'if (m/^(\w{1,2}?)(\d{2,}_.*)/) {mkdir $1; $_ = "$1/$1$2"}' * $ ls */* A/A01_.txt A/A02_.txt A/A03_.txt A/A04_.txt A/A05_.txt A/A06_.txt A/A07_.txt A/A08_.txt A/A09_.txt A/A1001_.txt A/A10_.txt AA/AA01_.txt AA/AA02_.txt AA/AA03_.txt AA/AA04_.txt AA/AA05_.txt AA/AA06_.txt AA/AA07_.txt AA/AA08_.txt AA/AA09_.txt AA/AA10_.txt Z/Z901_.txt Z/Z902_.txt Z/Z903_.txt Z/Z904_.txt Z/Z905_.txt Z/Z906_.txt Z/Z907_.txt Z/Z908_.txt Z/Z909_.txt Z/Z910_.txt ZZ/ZZ01_.txt ZZ/ZZ02_.txt ZZ/ZZ03_.txt ZZ/ZZ04_.txt ZZ/ZZ05_.txt ZZ/ZZ06_.txt ZZ/ZZ07_.txt ZZ/ZZ08_.txt ZZ/ZZ09_.txt ZZ/ZZ10_.txt