Bash

如何安全地將基於 REGEX 的文件移動和重命名到正確命名的目錄中

  • January 3, 2020

在一個大型驅動器中,我有數百個文件,每個文件的名稱都不同,但有幾個正則表達式。每個都附有隨機數,有時還附有字元。

例如,有 30 個文件以“television”一詞的變體命名,另外 50 個文件以“lightbulb”的變體命名。

問題是,由於多年前我在實現生成名稱的腳本時的糟糕編碼實踐,它非常不一致;所以我們可能會得到:

  • 電視139443.png
  • elevision244904.png
  • 電視097798.png
  • elevisio984882.png
  • _televisi90890890.png
  • 電視-911181.png

你明白了。該模式適用於所有文件“類別”——“電視”、“燈泡”、“汽車”等。幸運的是,每個文件名中至少有 5 個一致的字元在其他類別中不重複(十幾隻貓)。

我想要實現的是遞歸瀏覽混合文件夾,用正確的完整標題+附加創建日期重命名每個文件,並將它們移動到各自的文件夾中。

有點像:

  case : regex("levis"):
rename to Television-($creation_date).($extension)
mv to ~/Categories/Television/
break;
   case : regex("ghtbu"):
rename to Lightbulb-($creation_date).($extension)
mv to ~/Categories/Lightbulbs/
break;

顯然這不是正確的程式碼;這只是為了說明這個想法。我對日常的 bash/zsh 任務感到相當舒服,但不夠流利!

我還需要優雅地處理沒有匹配正則表達式的情況。

使用zsh,您可以根據其近似匹配特徵使用不同的方法:

autoload zmv # best in ~/.zshrc
zmodload zsh/stat

dest=~/Categories
categories=(television lightbulb motorcar etc)
mkdir -p -- $dest/${(C)^categories}

zmv -n '(**/)(*[^0-9])<->(.*)' \
      '$dest/${c::=${${(CM)categories:#(#a3)$2}:-unknown}}/$c-$(
         zstat -F %FT%T%z +mtime -- $f)$3'

在數組中${(M)categories:#(#a3)$2}查找$2(數字之前的部分)categories最多允許三個錯誤(不同的字元、轉置、插入、刪除)。

如果可以,請移除-n(試執行)。

對於您的方法,它可能類似於:

autoload zmv # best in ~/.zshrc
zmodload zsh/stat

dest=~/Categories
typeset -A categories

categories=(
 levis Television
 ghtbu Lightbulb
 otorc Motocar
)

mkdir -p -- $dest/$^categories

for k (${(k)categories}) (
 zmv -n "(**/)*$k*(.*)" '$dest/$categories[$k]/$categories[$k]-$(
         zstat -F %FT%T%z +mtime -- $f)$2'
)

或者,如果常見字元始終是第 3到第7個:

autoload zmv # best in ~/.zshrc
zmodload zsh/stat

dest=~/Categories

categories=(Television Lightbulb Motocar)

mkdir -p -- $dest/$^categories

for c ($categories) (
 zmv -n "(**/)*$c[3,7]*(.*)" '$dest/$c/$c-$(
         zstat -F %FT%T%z +mtime -- $f)$2'
)

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