サーバーに重複エントリを削除するプレフィックスを含むファイルのリストがあります。これらはまったく異なる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} フィールドを再度ランダム化せずに単に増加させるだけです。