ファイル拡張子を変更せずにファイル名を再帰的に変更するBashスクリプト

ファイル拡張子を変更せずにファイル名を再帰的に変更するBashスクリプト

ファイル拡張子を変更せずに、親ディレクトリとすべての子ディレクトリにあるすべてのファイル(.jpg、.jpeg、.movなど)の名前をdate_time_7digitnumberに変更しようとしています。以下のスクリプトはこれを行いますが、複数回実行され、すでに正しい内容が変更されます。以下は完全なスクリプトです。どんな助けでも大変感謝します!

システム:MacOS Monterey v12.5 Homebrewはgdateを使用するためにcoreutilをインストールしました。

#!/usr/bin/env bash

clear

RED='\033[0;31m'
NC='\033[0m'

shopt -s globstar nocaseglob nocasematch nullglob

echo
echo
echo -e "${RED}**********         Your current directory path is " $PWD "             **********${NC}"


read -p "

**********           This function is going to rename all media files with          ********** 

**********                            Date-Time-7digit number                       **********


**********                       !!THIS ACTION CAN NOT BE UNDONE!!                  **********

**********               !!MAKE SURE TO CHANGE TO THE CORRECT DIRECTORY!!           **********

      
      *** ARE YOU ABSOLUTELY SURE YOU ARE IN THE CORRECT DIRECTORY AND WISH TO PROCEED? ***

        
                                            [Y]es or [N]o  "  -n 1 -r



echo    # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]

then

n=1
for f in * ; do
   find . -type f -print0 |
        while IFS= read -r -d '' f ; do
            dd=$(dirname "$f")
            ext=${f##*.}
            new=$(gdate -r "$f" +"%Y%m%d_%H%M%S")-$(printf "%07d%s" "$n")
            mv -vn "$f" "$dd"/"$new"."$ext" ; ((n++))
        done 
      
done  

Echo

Echo Renaming Process Complete!

Echo

afplay /System/Library/Sounds/Ping.aiff

afplay /System/Library/Sounds/Ping.aiff

afplay /System/Library/Sounds/Ping.aiff

fi

ここに画像の説明を入力してください。

答え1

コードの次の部分を置き換えます。

n=1
for f in * ; do
   find . -type f -print0 |
        while IFS= read -r -d '' f ; do
            dd=$(dirname "$f")
            ext=${f##*.}
            new=$(gdate -r "$f" +"%Y%m%d_%H%M%S")-$(printf "%07d%s" "$n")
            mv -vn "$f" "$dd"/"$new"."$ext" ; ((n++))
        done 
      
done

このコードを通して:

DATE=$(date -r "$f" +"%Y%m%d_%H%M%S")
LOG="RENAME_${DATE}.log"    ; rm -f "${LOG}"
ERR="RENAME_${DATE}.err"    ; rm -f "${ERR}"

n=1
for f in *
do
    dd=$(dirname "$f")
    ext=${f##*.}
    new=${DATE}-$(printf "%07d%s" "$n")
        
    COM="mv -vn '${f}' '${dd}/${new}.${ext}'"

    ### LOG Everything for potential recovery action or later troubleshooting search
    echo "${new}.${ext}|${f}|${PWD}|${COM}"
    ${COM} >&2 2>>"${ERR}"

    ((n++))
done  >"${LOG}" 2>&1

目的は次のとおりです。

  • これ探すタスクは意味がありません(サブディレクトリの内容を見つけることを期待していますが、そうでないことを示唆していない限り)。
  • これしかし、find コマンドは消えた後は何もしません。
  • 各ファイルの日付を計算する作業を減らします(使用する必要がない限り必要ありません)。ファイルの実際の作成日に基づいてファイル名を指定します。
  • 今後の調査のために情報を記録し、
  • 実際の名前変更操作で報告された特定のエラーを記録します。

単純な「はい」応答(時には間違ったキーを押す)でスクリプトを実行するリスクがあるため、ディレクトリへのフルパスをコマンドライン引数として指定する必要があることに注意してください。スクリプトが意図した「ターゲット」を開始する前に、それを意識的に指定し、潜在的なディレクトリのリストを処理するためにバッチ内で呼び出すことができるツールにします。

関連情報