REGEXベースのファイルを正しい名前のディレクトリに安全に移動し、名前を変更する方法

REGEXベースのファイルを正しい名前のディレクトリに安全に移動し、名前を変更する方法

大きなドライブにはそれぞれ名前が異なりますが、正規表現を含む数百のファイルがあります。それぞれは乱数を追加し、場合によっては文字を追加します。

たとえば、「television」という単語の名前が変更された30個のファイルと、「lightbulb」の名前が変更された50個のファイルがあります。

問題は、数年前に名前を生成するためにスクリプトを実装するときに使用した誤ったコーディング方式のため、一貫性が非常に低下することです。

  • TV139443.png
  • TV244904.png
  • televisio097798.png
  • elevisio984882.png
  • _televisi90890890.png
  • TV-911181.png

あなたは理解しました。このモードは、「テレビ」、「電球」、「自動車」など、すべてのファイル「カテゴリ」に対して機能します。幸いなことに、各ファイル名には異なるカテゴリ(猫12匹)で繰り返されない少なくとも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操作に非常に満足していますが、十分にスムーズではありません!

また、正規表現の一致がない場合も適切に処理する必要があります。

答え1

を使用すると、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最大3つまで許可されています。間違い(他の文字、転置、挿入、削除)。

正常であれば削除します-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'
)

答え2

おそらく最も効率的なアプローチではないでしょう。しかし、私はこの問題を解決し、ファイル名の文字列をディレクトリと一致させ、現在の列挙型がランダムなので、一意の値を維持するために数をカウントします。

homedir=~/Categories
eval homedir=$homedir

cats="Television Lightbulb Bananas Motorcar"
declare -A count

for cat in $cats; do if [ ! -d $homedir/$cat ]; then mkdir -p $homedir/$cat; fi; done

while read f; do
    r=${f##*/}
    r=${r%.*}
    r=$(grep -Po "[a-z]+" <<<$r)
    for cat in $cats; do
        if [ $(grep -i "$r" <<< $cat) ]; then
            ((count[$cat]++))
            mv "$f" $homedir/$cat/$cat-$(printf "%03g" ${count[$cat]}).${f##*.}
        fi
    done
done <<< $(find ./banana/ -type f) 

一致しないコンテンツはgrep自動的にループを終了し、後で特別な注意を引くように所定の位置に残されます。

ファイル名の組み合わせに含める他の内容を入力できます。最終修正日は次のとおりです。

$(stat -c %Y $f)

など

関連情報