내 폴더에 mp3 파일이 잔뜩 있어요. 카세트 테이프로 녹음되었으며 개별 트랙을 분리해야 했습니다. 이는 파일 이름 중 하나입니다.
Gobbolino the Witch's Cat, 10:52 The Hare & Tortoise, 14:52 The Shoe Tree, 24:22 The Emperors New Clothes, 34:11 The Red Nightcaps, 37:07 Aldo in Arcadia (1), 40:37 The Forest Troll.mp3
각 트랙의 시작을 나타내는 파일 이름에 타임스탬프가 있는 것을 볼 수 있습니다. 첫 번째 트랙은 항상 00:00에 시작하므로 타임스탬프가 없습니다. 마지막 트랙은 항상 mp3의 끝 부분에 있어야 합니다. 어떻게든 별도의 파일을 만들기 위해 이러한 타임스탬프를 추출하고 싶습니다.
위 파일이 올바르게 분할되면 출력은 다음과 같습니다.
Gobbolino the Witch's Cat.mp3
The Hare & Tortoise.mp3
The Shoe Tree.mp3
The Emperors New Clothes.mp3
The Red Nightcaps.mp3
Aldo in Arcadia (1).mp3
The Forest Troll.mp3
파일을 반복하는 방법과 ffmpeg를 사용하여 파일을 자르는 방법을 알고 있지만 파일 이름에서 타임스탬프와 트랙 이름을 추출하는 방법을 모르겠습니다. 저는 zsh를 사용하고 있으며 이것이 현재 코드입니다.
for file in *; do
if [[ -f "$file" ]]; then
# extract timestamps and loop thru, for each timestamped section
ffmpeg -ss TIMESTAMP_START -to TIMESTAMP_END -I "$file" -acodec copy TRACK_NAME.mp3
fi
done
고쳐 쓰다
이 질문에 대한 나의 기준이 바뀌었습니다. 파일 이름은 다음과 같습니다.
Tape 1 - Gobbolino the Witch's Cat, 11-06 The Hare & Tortoise, 14-25 The Shoe Tree, 24-06 The Emperors New Clothes, 34-27 The Red Nightcaps, 37-29 Aldo in Arcadia (1), 40-40 The Forest Troll.mp3
즉, 시작 부분에 앨범 이름이 있고 타임스탬프에 콜론 대신 하이픈이 있습니다(macOS에서는 파일 이름에 콜론이 있을 수 없음). 또한 일부 mp3 태그를 파일에 삽입하고 각 앨범의 트랙을 자체 앨범 폴더에 넣고 싶습니다.
내 솔루션은 아래 Gilles 중 하나를 기반으로 합니다. 스크립트는 다음과 같습니다.
setopt interactive_comments
for file in *(.); do
extension=$file:e
rest=$file:r
timestamp_start=0:00
timestamp_duration=$(ffprobe -i "$file" -show_entries format=duration -v quiet -of csv="p=0" -sexagesimal -sexagesimal)
timestamp_duration=${timestamp_duration%.*}
tracknum=1
while [[ $rest =~ ,\ *([0-9:]+-[0-9][0-9])\ * ]]; do
track_name="$rest[1,$MBEGIN-1]"
if [[ "$track_name" == *"Tape "* ]]; then
albumname="${track_name%% - *}"
track_name="${track_name#* - }"
echo "\n\nALBUM NAME $albumname\n"
mkdir $albumname
fi
rest=$rest[$MEND+1,-1]
timestamp_end=$match[1]
timestamp_end="${timestamp_end//-/:}"
# echo "$timestamp_start $timestamp_end $track_name.$extension"
ffmpeg -ss $timestamp_start -to $timestamp_end -i $file -acodec libmp3lame -ac 2 -ab 256k -ar 44100 -metadata album="$albumname" -metadata title="$track_name" -metadata track="$tracknum" $track_name.$extension
mv $track_name.$extension $albumname
timestamp_start=$timestamp_end
tracknum=$((tracknum+1))
last_track_name="$rest:r"
done
if [[ -n $timestamp_end ]]; then
# echo "$timestamp_start $timestamp_duration $last_track_name.$extension"
ffmpeg -ss $timestamp_start -to $timestamp_duration -i $file -acodec libmp3lame -ac 2 -ab 256k -ar 44100 -metadata album="$albumname" -metadata title="$last_track_name" -metadata track="$tracknum" $last_track_name.$extension
mv $last_track_name.$extension $albumname
fi
done
답변1
트랙 구분 기호와 일치하도록 정규식을 사용하여 파일 이름을 반복합니다.=~
조건식 연산자. 정규식은 ,\ *([0-9:]+:[0-9][0-9])\ *
쉼표와 그 뒤에 선택적으로 주변 공백이 있는 타임스탬프를 일치시킵니다.
$file:e
$file:r
파일 확장자를 추출 하여역사적 수정.
모든 파일을 반복한 다음 일반 파일만 일치시키는 대신 다음을 사용하십시오.글로벌 예선일반 파일만 일치합니다.
for file in *(.); do
extension=$file:e
rest=$file:r
timestamp_start=0:00
timestamp_end=
while [[ $rest =~ ,\ *([0-9:]+:[0-9][0-9])\ * ]]; do
track_name=$rest[1,$MBEGIN-1]
rest=$rest[$MEND+1,-1]
timestamp_end=$match[1]
ffmpeg -ss $timestamp_start -to $timestamp_end -I $file -acodec copy $track_name.$extension
timestamp_start=$timestamp_end
done
if [[ -n $timestamp_end ]]; then
ffmpeg -ss $timestamp_end -I $file -acodec copy $rest.$extension
else
: # If you want special processing for single-track files, it goes here.
fi
done
답변2
awk -F "," '{for(i=1;i<=NF;i++){gsub(/[0-9]{2}:[0-9]{2}/,"",$i);gsub(/^[[:space:]]*/,"",$i);print $i".mp3"}}' file.txt
산출
Gobbolino the Witch's Cat.mp3
The Hare & Tortoise.mp3
The Shoe Tree.mp3
The Emperors New Clothes.mp3
The Red Nightcaps.mp3
Aldo in Arcadia (1).mp3
The Forest Troll.mp3.mp3