Linux

如果匹配文件的數量大於 10,如何將匹配某個名稱的所有文件移動到新文件夾?

  • November 16, 2017

我正在尋找創建一個腳本,在執行時它將查看一個目錄並蒐索所有文件,然後自動發現文件名模式,然後根據下面所述的其他邏輯移動它們。

假設我在一個文件夾中有以下文件:

  • 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

引用自:https://unix.stackexchange.com/questions/404830