我从Google外卖中提取了一堆图像文件,格式为yyyy-MM-dd / img.jpg-我使用phockup整理照片,并且需要将照片保存在yyyy / mm / dd文件夹中。我想保留日期,因为Google已经给了他们。
例如-此文件夹/图像应匹配
/2018-07-01/test_img.jpg
并重命名为
/2018/07/01/test_img.jpg
我尝试将bash与sed一起使用,并发现使用正则表达式捕获组来移动文件,但是我似乎运气不高。请参阅下面的当前位置
find . -name "*.jpg" -print0 | sed 'p;s/([0-9]{4})\-([0-9]{2})\-([0-9]{2})\/(.*)/$2\/$3\/$4\/$5/' | xargs -0 -n2 mv
这是我遇到的错误
mv:无法将'./2018-07-01/test_img.jpg'移至“ $'\ n”。/2018-07-01 / test_img.jpg':无此类文件或目录
自从我认为正则表达式捕获组是正确的以来,这似乎很奇怪。我不确定为什么它不会重命名文件。
答案 0 :(得分:1)
这里有重击的可能。在带有日期命名目录的目录中运行脚本。我使用了复制命令而不是移动,因此可以在删除旧文件之前检查结果。如果您想改用mv,请至少运行一次,并在其前面加上echo以进行健全性检查。
newdir=/home/me/newpics
[[ -d "$newdir" ]] || mkdir "$newdir"
for dir in *; do
if [[ -d "$dir" && "$dir" =~ ([0-9]+)-([0-9]+)-([0-9]+) ]]; then
year=${BASH_REMATCH[1]}
month=${BASH_REMATCH[2]}
day=${BASH_REMATCH[3]}
todir="$newdir/$year"; [[ -d "$todir" ]] || mkdir "$todir"
todir+="/$month"; [[ -d "$todir" ]] || mkdir "$todir"
todir+="/$day"; [[ -d "$todir" ]] || mkdir "$todir"
for file in "$dir/"*.jpg; do
base=$(basename "$file")
cp "$file" "$todir/$base"
done
fi
done
答案 1 :(得分:0)
除了我上面的评论之外,要使用{n}
出现次数,您将需要除 basic 正则表达式之外的其他内容,如果我正确理解,您只想匹配.jpg
格式的文件,例如/2018-07-01/test_img.jpg
,那么您将需要限制find
表达式以仅在日期格式的目录中查找文件,或者可以使sed
仅传递那些目录中的文件。 sed
可以只匹配给定格式的行,然后尝试使用以下格式进行替换:
sed -r /match/s/find/replace/
(注意:,-r
选项使sed
使用 extended 正则表达式,请查看手册页(man sed
)为了确保您的版本也支持该选项,-E
通常用于相同目的)
对于上面的match
,您可以使用:
/^\/[0-9]{4}-[0-9]{2}-[0-9]{2}/
此外,-n
的{{1}}选项禁止输出的默认打印。因此,要制作仅作用于sed
并将其传递给xargs
的表达式,可以使用以下sed
表达式:
sed -r -n '/^\/[0-9]{4}-[0-9]{2}-[0-9]{2}/s/([0-9]{4})\-([0-9]{2})\-([0-9]{2})\/(.*)/\1\/\2\/\3\/\4/p'
(注意:将'$'
替换为\
,以调用所需的 backreference 并将反向引用号调整为1-4
而不是2-5
,并且在替换后添加p
会使sed
打印与表达式匹配的行)