ファイル名の競合なしでファイルの配置で文字列を検索および置換する

ファイル名の競合なしでファイルの配置で文字列を検索および置換する

私は長年にわたって収集されたランダムで無駄なファイル名を持つ何千ものファイルを含むディレクトリツリーを持っています。

私はそれらを整理し、関連性を維持し、特定の単語を削除したいが、重複したファイル名を生成したくないと思います。

例えば

WONDERBROS - PAWG Remy LaCroix Gets BREAKFAST! (pwg11717) - SOMENAME.mp4

次のような名前に変更したいと思います。

WONDERBROS.PAWG.Remy.LaCroix.Gets.BREAKFAST!.(pwg11717).mp4

だからいくつかのポイントがあります。

  • すべてのスペースを次に置き換えます。.
  • SOMENAMEが表示されるたびに削除してください。
  • 名前を変更する前にファイル名がすでに存在することを確認し、数字が追加されたら何も上書きしないように一意のファイル名になるまで続けてください。

シェルスクリプトを通しても可能なようですが、おすすめのツールがあればそれも試してみたいと思います。

似たようなことを試しましたが、最初の行だけが機能しているようです。

# find and replace spaces with .
find /home/matt/rename_test_tmp/ -depth -name "* *" -execdir rename 's/ /./g' "{
# find and replace somename with .
find /home/matt/rename_test_tmp/ -depth -name "somename" -execdir rename 's/ 
# find and replace SOMENAME
find /home/matt/rename_test_tmp/ -depth -name "SOMENAME" -execdir rename 's/ 
# find and replace Somename
find /home/matt/rename_test_tmp/ -depth -name "Somename" -execdir rename 's/ 

私の問題は、私はまだreg exを理解していないということですか?

ベストアンサー1

これが基本構造です。問題が発生すると、MAXTRYSは名前の変更を停止します。合理的な値を選択してください。

#!/bin/bash
#
# Usage: 
#       numberedMove xy-file.txt TARGETDIR 
#
file="$1"
targetDir="$2"
MAXTRYS=666
#
# @TODO
# add tests for permissions, maybe handle symlinks etc.
#
test -f "$file" || {
    echo No such file "$file" or not an ordinary file
    exit 1;
}

test -d "$targetDir" || {
    echo No such directory "$targetDir"
    exit 2;
}

#
# append NUM+1 to filename, to create unique name
#
numbered () {
  fname="$1"
  num=$2
  if [[ $num -gt $MAXTRYS ]]
  then
    echo " giving up - max trys: $MAXTRYS "
    exit 3
  fi
  # echo "mv $fname → $targetDir/$fname$num"
  test -f "$targetDir/$fname$num" && numbered "$fname" $((num+1)) || mv "$file" "$targetDir/$fname$num"
}

#
# remove all SOMENAME and replace every blank with a dot
#
filtername () {
   fname="$1"
   fname=${fname//SOMENAME/}
   fname=${fname// /.}
   echo "$fname"
}
#
# filter filename, if unique: move, else move with number suffix
#
if [[ -e "$file" ]]
then
    newname=$(filtername "$file")
    if [[ ! -f "$targetDir/$newname" ]]
    then
        # echo "mv $file → $targetDir/$newname"
        mv "$file" "$targetDir/$newname"
    else
        # echo "mv $file → $targetDir/$newname NUMBERED"
        numbered "$newname" 1
    fi
fi

より多くのルールを追加して既存のルールを変更できますfiltername

これが私自身のニーズのためのものであれば、ドットはかなり弱いインジケータ(a.tar.bz2)であるため、スペースを「」。代わりに「-」に変更します。

代わりに、複数の区切り文字を1つに縮小します。

    mv "ab cd - SOMENAME..mp3" → "./B/ab.cd.-...mp3" 
    mv "ab cd - SOMENAME..mp3" → "./B/ab-cd-.mp3" 

ファイル拡張子を保持し、最後の拡張子の前に数字を入れます。

    mv "ab cd- SOMENAME..mp3"  → "./B/ab-cd-0.mp3" 
    mv "ab cd - SOMENAME..mp3" → "./B/ab-cd-1.mp3" 
    mv "ab cd -SOMENAME..mp3"  → "./B/ab-cd-2.mp3" 

多くのプログラムが拡張機能を解釈するためです。

約10個のファイルでのみプログラムをテストしたため使用前にバックアップしてください、操作が成功したことを確認します(合計ファイルサイズとファイル数で可能)。

私のテスト:

for f in a* ; do ./numberedMove.sh "$f" ./B ; done

プログラムをCWDに配置すると、それ自体が移動できることに注意してください。

おすすめ記事