Linux
如果匹配文件的數量大於 10,如何將匹配某個名稱的所有文件移動到新文件夾?
我正在尋找創建一個腳本,在執行時它將查看一個目錄並蒐索所有文件,然後自動發現文件名模式,然後根據下面所述的其他邏輯移動它們。
假設我在一個文件夾中有以下文件:
- aaa.txt
- temp-203981.log
- temp-098723.log
- temp-123197.log
- temp-734692.log
- test1.sh
- test2.sh
- test3.sh
該腳本應該能夠自動搜尋該目錄,並且應該會發現有 4 個文件 (temp-XXX.log) 和 3 個文件 (testXXX.sh) 的名稱中有匹配的前綴。然後一旦找到文件的數量,它應該將其與定義的限制進行比較,比如 3。
如果與指定名稱匹配的文件數大於限制,則應將找到的文件移動到以匹配的文件名部分命名的文件夾中。
所以上面的父文件夾現在應該如下所示:
- aaa.txt
- temp.log(這將是包含 temp-734692.log、temp-123197.log、temp-098723.log、temp-203981.log 的文件夾)
- test.sh(這將是包含 test1.sh、test2.sh、test3.sh 的文件夾)
希望這是有道理的。
PS 我正在為這個腳本使用 ASH,所以它需要能夠在沒有許多花哨的 bash 能力的情況下執行,否則這會更容易。
謝謝!
編輯:一開始的清晰度變化。此外,如果我提供一個預定的分隔符,比如“&”,所有文件名都將具有該分隔符,這可能會更容易。該腳本仍然需要根據分隔符之前的文件名創建變數文件夾名稱,但我認為這會使事情變得更加清晰和容易。
檢查,它是否有效,我將添加解釋,它是如何工作的。我在
dash
.**注意:**文件名不應包含空格、換行符。
#!/bin/dash limit=1 printf "%s\n" * | sed 's/[-0-9]*\..*$//' | uniq -c | awk -v lim=${limit} '$1 >= lim {print $2}' | sort -r | while read -r i; do for j in "${i}"*; do [ -f "$j" ] || continue dir=${i}.${j#*.} [ -d "$dir" ] || mkdir "$dir" mv -v "$j" "$dir" done done
這裡有一個問題 - 當文件名等於將來的目錄名時,例如
aaa.txt
. 在這種aaa.txt
情況下,文件名沒有任何多餘的字元,因此不會從中刪除任何內容,因此,新目錄名將相同,這會導致錯誤:mkdir: cannot create directory ‘aaa.txt’: File exists mv: 'aaa.txt' and 'aaa.txt' are the same file
此問題的一種解決方法是檢查假定的目錄名稱是否等於文件名,然後在將來的目錄名稱中添加一些數字,例如
aaa1.txt
.示範
在腳本執行之前。
$ tree . ├── aaa.txt ├── temp-098723.log ├── temp-123197.log ├── temp-203981.log ├── temp-734692.log ├── temp-new-file123.log ├── temp-new-file-2323-12.log ├── temp-new-file-342.log ├── test1.sh ├── test2.sh └── test3.sh 0 directories, 11 files
腳本執行後:
script.sh
$ tree . ├── aaa.txt ├── temp.log │ ├── temp-098723.log │ ├── temp-123197.log │ ├── temp-203981.log │ └── temp-734692.log ├── temp-new-file.log │ ├── temp-new-file123.log │ ├── temp-new-file-2323-12.log │ └── temp-new-file-342.log └── test.sh ├── test1.sh ├── test2.sh └── test3.sh 3 directories, 11 files