我正在编写一个BASH脚本,除其他外,它根据开始日期和结束日期的输入参数将文件从一个目录复制到另一个目录。文件名的格式为YYYYMMDDhhmmss.jpg
,例如20161230143922.jpg
。我正在使用find ... -exec cp {} ...
,因为源目录中有数万个文件。输入参数是格式为YYYYMMDD
的开始日期和结束日期。
我知道我不能在($startdate..$enddate)
这样的正则表达式中做一个简单的范围,但我无法弄清楚如何以编程方式生成一个可行的正则表达式。如果我的文件较少,我可以cp {$startdate..$enddate} destination
,但唉,我认为这不可行。
我想复制介于0500和1700之间的$startdate
和$enddate
之间的所有文件。这包括20170102060635.jpg
和20170104131255.jpg
等图片,但是不是20170103010022.jpg
。
这是我到目前为止所做的:
#!/bin/bash
STARTDATE=$1
ENDDATE=$2
FILE_NAME="review-${STARTDATE}-${ENDDATE}.mp4"
if [[ -n "$STARTDATE" ]]; then
echo "STARTDATE: $STARTDATE"
else
echo "Invalid start date: '$STARTDATE'"
echo "Syntax: ./create_time_lapse_date_range.sh <startdate> <enddate>"
exit
fi
if [[ -n "$ENDDATE" ]]; then
echo "ENDDATE: $ENDDATE"
else
echo "Invalid end date: '$ENDDATE'"
echo "Syntax: ./create_time_lapse_date_range.sh <startdate> <enddate>"
exit
fi
cd ~/Desktop/test\ timelapse
# Copy relevant files to local directory
find ~/Desktop/originals -regex "???????????????" -exec cp {} ~/Desktop/test\ timelapse/ \;
# Rename files to be sequential serial numbers
find ~/Desktop/test\ timelapse -name "*.jpg" | awk 'BEGIN{ a=0 }{ printf "mv \"%s\" ~/Desktop/\"test\ timelapse/%06d.jpg\"\n", $0, a++ }' | bash
# Generate timelapse video
ffmpeg -framerate 25 -i %06d.jpg -c:v libx264 -r 25 ${FILE_NAME}
答案 0 :(得分:1)
正则表达式不是处理数值范围的最佳工具,因此您可能需要考虑在正则表达式本身之外包含一些逻辑的解决方案。像这样:
REGEX="([0-9]{8})([0-9]{4})"
for f in ~/Desktop/originals/*.jpg
do
if [[ $f =~ $regex ]]
then
datepart=${BASH_REMATCH[1]}
timepart=${BASH_REMATCH[2]}
#if the DATE part matches
if (( $STARTDATE <= $datepart )) && (( $datepart <= $ENDDATE ))
then
#if the TIME part matches
if [[ $timepart =~ "(0[5-9]|1[0-7])" ]]
then
# copy file ...
fi
fi
fi
done
纯正则表达式解决方案
如果您真的想要纯正的正则表达式解决方案,这将有助于展示复杂性。这是一个正则表达式,用于查找2017年1月的日期0500到1700时间范围内的所有文件:^201701\d{2}(0[5-9]|1[0-7])\d{4}\.jpg$
请注意匹配0500到1700之间所需的正则表达式模式:
(0[5-9]|1[0-7])
它并不漂亮,并且具有硬编码范围。要处理动态的开始和结束日期,您将动态构建类似的模式。它可以完成,但为什么要使用正则表达式呢?
以下是一个示例,显示了从20161225到20170114的日期范围需要生成的内容:
^(201612(2[5-9]|3\d)|201701(0\d|1[0-4]))(0[5-9]|1[0-7])\d{4}\.jpg$