同じプレフィックスを共有するバッチの名前変更ファイル

同じプレフィックスを共有するバッチの名前変更ファイル

サーバーに重複エントリを削除するプレフィックスを含むファイルのリストがあります。これらはまったく異なるmakefileです。

生成されたファイルのようです。

{Title} - {yyyy-MM-dd}_{random} - {Description}.ts

たとえば、

Camera Recording - 2023-08-11_14 - Front Deck.ts
Camera Recording - 2023-08-11_14 - Back Deck.ts
Camera Recording - 2023-08-16_27 - Front Deck.ts
Camera Recording - 2023-08-16_36 - Front Deck.ts
Camera Recording - 2023-08-17_56 - Front Deck.ts

次のファイル名の重複プレフィックスを識別するスクリプトを実行できる必要があります。次に、日付の後にある数字のプレフィックス{random}部分を変更します。

Camera Recording - 2023-08-11_14 - Front Deck.ts
Camera Recording - 2023-08-11_14 - Back Deck.ts

次のようになるには、{random}を別の値(14を除く)に置き換える必要があります。

Camera Recording - 2023-08-11_14 - Front Deck.ts
Camera Recording - 2023-08-11_68 - Back Deck.ts

Linuxシェルスクリプトを使用してこれを達成する方法に関する提案はありますか?

答え1

ファイル名に改行文字を含めることができない場合は、POSIX awkを使用してください。

$ cat tst.sh
#!/usr/bin/env bash

while IFS= read -r file; do
    if (( cnt++ % 2 )); then
        echo mv -- "$old" "$file"
    fi
    old="$file"
done < <(
    printf '%s\n' *.ts |
    awk '
        match($0,/ - [0-9]{4}(-[0-9]{2}){2}_[0-9]+ - /) {
            beg = substr($0,1,RSTART+13)
            pfx = substr($0,RSTART+14,RLENGTH-17)
            end = substr($0,RSTART+RLENGTH-3)

            maxPfx[beg] = ( pfx > maxPfx[beg] ? pfx : maxPfx[beg] )
            key = beg RS pfx
            ends[key,++cnt[key]] = end
        }
        END {
            for ( key in cnt ) {
                split(key,begPfx,RS)
                beg = begPfx[1]
                for ( i=2; i<=cnt[key]; i++ ) {
                    pfx = begPfx[2]
                    end = ends[key,i]
                    printf "%s%s%s\n", beg, pfx, end
                    pfx = ++maxPfx[beg]
                    printf "%s%s%s\n", beg, pfx, end
                }
            }
        }
    '
)

$ ./tst.sh
mv -- Camera Recording - 2023-08-11_14 - Back Deck.ts Camera Recording - 2023-08-11_15 - Back Deck.ts

上記のコードは、文字列(日付を含む)の既存の最も高いプレフィックス番号より大きい1から始まる新しいプレフィックス番号に重複するアイテムを移動します。任意の数字を新しいプレフィックスとして使用することはできません。そうしないと、既存のプレフィックスと同じ新しいプレフィックスが発生する可能性があります。

テストが完了したら削除しますecho

答え2

ここに解決策があります。 Bash 5以上が必要です。

#!/bin/bash
declare -A SEEN
for FN in *.ts; do
    if [[ $FN =~ ('Camera Recording - ')([0-9]{4}-[0-9]{2}-[0-9]{2}_)([0-9]+)( .*) ]]; then
        BEFORE=${BASH_REMATCH[1]}
        DATE=${BASH_REMATCH[2]}
        RNDM=${BASH_REMATCH[3]}
        AFTER=${BASH_REMATCH[4]}

        KEY=$DATE$RNDM
        if [[ $BASH_VERSION < '5.2.0' ]]; then
            # Workaround for a bug in Bash fixed in 5.2.0
            KEY=${KEY@Q}
        fi
        while [[ -n ${SEEN[$KEY]} && $RNDM -lt 1000 ]]; do
            (( ++RNDM ))
            KEY=$DATE$RNDM
        done
        SEEN[$KEY]=1

        NEW_FILENAME=$BEFORE$DATE$RNDM$AFTER
        if [[ $FN != "$NEW_FILENAME" ]]; then
            mv -iv -- "$FN" "$NEW_FILENAME"
        fi
    fi
done

{random} フィールドを再度ランダム化せずに単に増加させるだけです。

関連情報