내 서버에 중복 항목을 제거하려는 접두어가 포함된 파일 목록이 있습니다. 이들은 완전히 다른 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} 필드를 다시 무작위화하지 않고 단지 증가시킬 뿐입니다.