We have a (quiet good) Panasonic miniDV camcorder to save our Little Boy's moments. Software comes with the device can auto index the tape by recoreded date attribute and then batch capture (copy) all the movie to hard disk. It's wonderful feature, except the filenames — we got something like this for every tape:
phan@phan-laptop:/mnt/TQA/Videos/Sushi-1Y/08.03.09-31.05.09$ ls
hsicon.stg MOVIE0006.avi MOVIE0012.avi MOVIE0018.avi MOVIE0024.avi MOVIE0030.avi
MOVIE0001.avi MOVIE0007.avi MOVIE0013.avi MOVIE0019.avi MOVIE0025.avi MOVIE0031.avi
MOVIE0002.avi MOVIE0008.avi MOVIE0014.avi MOVIE0020.avi MOVIE0026.avi MOVIE0032.avi
MOVIE0003.avi MOVIE0009.avi MOVIE0015.avi MOVIE0021.avi MOVIE0027.avi TAPE08032009_1902.tap
MOVIE0004.avi MOVIE0010.avi MOVIE0016.avi MOVIE0022.avi MOVIE0028.avi
MOVIE0005.avi MOVIE0011.avi MOVIE0017.avi MOVIE0023.avi MOVIE0029.avi
Naturally, it is wanted to rename the movies to show the recorded date and, maybe, some other userful information. Although I like Métamorphose and other batch renaming tools, they can't extract video data. So I decided to create my own bash script. Here is it:
#!/bin/bash
# Bash script for batch renaming of video files, recored by a miniDV-tape
# camcorder, based on the media information (Recorded Date in my case).
# Created by Phan Vinh Thinh, teppi {-} vnoss.org,
# released 01 Feb 2010 under GPL, so feel free to make changes.
# In the script used some echo commands for diagnostic purpose
###############################################################################
# If there is not any given argument (filename), print the help message
if [ $# -eq 0 ]; then
echo "vrename.sh --- Bash script for batch video files renaming";
echo "Usage: ./vrename.sh [files]";
echo "Examples:";
echo -e "\t./vrename.sh *.avi";
echo -e "\t./vrename.sh MOVIE0001.avi MOVIE0002.avi MOVIE0005.avi";
fi;
#for FILE in MOVIE*.avi; do
# $@ expands to all command-line parameters separated by spaces
for FILE in $@; do
# Get the Recorded Date in YYYYMMDDhhmm format and then
# assign to TIME variable
TIME=`mediainfo $FILE | grep -i "recorded date" | cut -d ':' --field=2-3 | \
tr -cd [:alnum:]`;
#echo $TIME;
# Bash script for batch renaming of video files, recored by a miniDV-tape
# camcorder, based on the media information (Recorded Date in my case).
# Created by Phan Vinh Thinh, teppi {-
# released 01 Feb 2010 under GPL, so feel free to make changes.
# In the script used some echo commands for diagnostic purpose
###############################################################################
# If there is not any given argument (filename), print the help message
if [ $# -eq 0 ]; then
echo "vrename.sh --- Bash script for batch video files renaming";
echo "Usage: ./vrename.sh [files]";
echo "Examples:";
echo -e "\t./vrename.sh *.avi";
echo -e "\t./vrename.sh MOVIE0001.avi MOVIE0002.avi MOVIE0005.avi";
fi;
#for FILE in MOVIE*.avi; do
# $@ expands to all command-line parameters separated by spaces
for FILE in $@; do
# Get the Recorded Date in YYYYMMDDhhmm format and then
# assign to TIME variable
TIME=`mediainfo $FILE | grep -i "recorded date" | cut -d ':' --field=2-3 | \
tr -cd [:alnum:]`;
#echo $TIME;
YEAR=${TIME%????????};
MIN=${TIME#??????????};
HOUR=${TIME#????????};
HOUR=${HOUR%$MIN};
DAY=${TIME#??????};
DAY=${DAY%$HOUR$MIN};
MON=${TIME%??????};
MON=${MON#$YEAR};
# echo $DAY-$MON-$YEAR-$HOUR-$MIN;
# Change month to short name format (Jan, Feb, etc)
if [ "$MON" = "01" ] ; then
Month=Jan;
elif
[ "$MON" = "02" ]; then
Month=Feb;
elif
[ "$MON" == "03" ]; then
Month=Mar;
elif
[ "$MON" = "04" ] ; then
Month=Apr;
elif
[ "$MON" = "05" ] ; then
Month=May;
elif
[ "$MON" = "06" ] ; then
Month=Jun;
elif
[ "$MON" = "07" ] ; then
Month=Jul;
elif
[ "$MON" = "08" ] ; then
Month=Aug;
elif
[ "$MON" = "09" ] ; then
Month=Sep;
elif
[ "$MON" = "10" ] ; then
Month=Oct;
elif
[ "$MON" = "11" ] ; then
Month=Nov;
elif
[ "$MON" = "12" ] ; then
Month=Dec;
else
echo "Try without any argument to see help!"
exit 1;
fi;
# echo $Month;
# Assign NAME variable --- basename for future filename
NAME=Movie-$DAY$Month$YEAR-$HOUR$MIN;
# echo $NAME;
# Rename FILE to NAME.avi
# Use -i option to make sure there are not 2 files with same NAME
mv -i -v $FILE $NAME.avi;
done
(To obtain media information, we need an external program — mediainfo).
You can download the script in gzip format from my Google Docs share.
Running script, we got:
phan@phan-laptop:/mnt/TQA/Videos/Sushi-1Y/08.03.09-31.05.09$ ~/vrename.sh *.avi
`MOVIE0001.avi' -> `Movie-08Mar2009-1902.avi'
`MOVIE0002.avi' -> `Movie-08Mar2009-1904.avi'
`MOVIE0003.avi' -> `Movie-08Mar2009-1905.avi'
`MOVIE0004.avi' -> `Movie-08Mar2009-1906.avi'
`MOVIE0005.avi' -> `Movie-08Mar2009-1907.avi'
`MOVIE0006.avi' -> `Movie-16Mar2009-1244.avi'
`MOVIE0007.avi' -> `Movie-16Mar2009-1252.avi'
`MOVIE0008.avi' -> `Movie-16Mar2009-1339.avi'
...
`MOVIE0003.avi' -> `Movie-08Mar2009-1905.avi'
`MOVIE0004.avi' -> `Movie-08Mar2009-1906.avi'
`MOVIE0005.avi' -> `Movie-08Mar2009-1907.avi'
`MOVIE0006.avi' -> `Movie-16Mar2009-1244.avi'
`MOVIE0007.avi' -> `Movie-16Mar2009-1252.avi'
`MOVIE0008.avi' -> `Movie-16Mar2009-1339.avi'
...
P.S. It's time to start Perl learning ;).
4 comments:
Ờ.. tới giới hạn của bash rồi. Cái if/else cho tháng có thể dùng case/esac cho gọn. Muốn gọn hơn nữa thì đút thông tin cho "date --date=..." rồi nhờ "date" định dạng output dùm.
Với mấy cái script phức tạp như vầy thì nên thêm tuỳ chọn --dry-run để chỉ in những lệnh sẽ làm chớ không làm, để kiểm tra trước.
Bạn đồng ý dùng case/esac thay vì if/else (thanks), nhưng không thích dùng date vì không linh hoạt bằng dùng các biến.
Bạn đang nghiên cứu để thêm cái --dry-run vì thấy nó thật có ích. Tuy nhiên, thêm tùy chọn sẽ làm cái script phức tạp. Tạm thời nó phục vụ ngon lành cho nhu cầu của bạn.
* mấy ngày tháng đó thì dùng mảng luôn, khỏi if-then-case cho mệt
* dry-run thì chỉ việc thêm cái option trước khi mv là xong
if [ "x$1" == "x-dry-run"]; then
dry_run="echo"
else
dry_run=“”
fi
rồi dùng với mv:
$dry_run mv xxx yyy
-dry-run làm như bạn nói cũng OK. Tuy nhiên, vì tôi dùng $@ nên option này sẽ rơi vào vòng lặp như các tập tin *.avi. Mặc dù không có gì đáng sợ, nhưng muốn theo đúng chuẩn bash scripting thì có lẽ phải động đến getopt hoặc getopts.
Post a Comment