我想重命名以下格式的文件:
img_MM-DD-YY_XX.jpg
img_MM-DD-YY_XXX.jpg
至:
newyears_YYYY-MM-DD_XXX.jpg
地点:
我想出了这个脚本,但它不起作用:
for filename in ?*.jpg; do
newFilename=$(echo $filename | \
sed 's/img_\(.*\)-\(.*\)-\(.*\)_\([0-9][0-9]\)\./newyears_20\3-\1-\2_0\4./;
s/img_\(.*\)-\(.*\)-\(.*\)_\([0-9][0-9][0-9]\)/newyears_20\3-\1-\2_\4/' -)
mv $filename $newFilename
done
任何帮助将不胜感激。
你可以在 bash 中尝试这个脚本:
for filename in *.jpg; do
newFilename=$(sed -E 's#img_([0-9]{1,2})-([0-9]{1,2})-([0-9]{1,2})_(.*)$#newyears_20\3-\2-\1_\4#' <<< "$filename")
mv "$filename" "$newFilename"
done
sed -E
也得到 gnu sed
的支持。
没有 for 循环。
ls | grep 'jpg$' | sed '
#Save the original filename
h
#Do the replacement
s/img_\(.*\)-\(.*\)-\(.*\)_\([0-9][0-9]\)\./newyears_20\3-\1-\2_0\4.//
s/img_\(.*\)-\(.*\)-\(.*\)_\([0-9][0-9][0-9]\)/newyears_20\3-\1-\2_\4//
#Bring the original filename back
x
G
s/^\(.*\)\n\(.*\)$/mv "\1" "\2"' | bash
在 mv 之前省略管道到 bash 以查看结果
感谢 http://www.gnu.org/software/sed/manual/sed.html#Rename-files-to-lower-case
这个简单的变体对我有用:
$ cat mapper
for filename in ?*.jpg
do
newFilename=$(echo $filename | \
sed -e 's/img_\(.*\)-\(.*\)-\(.*\)_\([0-9][0-9]\)\./newyears_20\3-\1-\2_0\4./' \
-e 's/img_\(.*\)-\(.*\)-\(.*\)_\([0-9][0-9][0-9]\)/newyears_20\3-\1-\2_\4/')
echo mv $filename $newFilename
done
$ echo > img_04-23-09_123.jpg
$ echo > img_08-13-08_33.jpg
$ sh mapper
mv img_04-23-09_123.jpg newyears_2009-04-23_123.jpg
mv img_08-13-08_33.jpg newyears_2008-08-13_033.jpg
$
唯一的区别是使用显式的
-e
选项代替分号。
在 MacOS X 10.6.7 上测试。
我记得曾经搞过这种事情。我发现创建一个脚本来执行您想做的事情通常很有用:
即。脚本的输出将是一个如下文件:
mv file1 file2
mv file3 file4
.....
mv fileN fileM
要创建它,只需执行 ls | grep 日期模式 | sed 脚本将 mv file1 粘贴到 file2 > myscript
然后执行./myscript
这样您就可以更好地查看中间输出以找出问题所在。
它可以通过纯粹的 bash 脚本来处理。
for j in ?*.jpg
do
n="newyears_20${j:10:2}-${j:4:2}-${j:7:2}";
if [ ${j:15:1} = "." ];then
n="${n}_0${j:13}"
else
n="${n}${j:12}"
fi
mv $j $n
done
你不需要正则表达式。只需使用重命名即可:
rename img_ newyears_ img_*.jpg
如果你想使用 mv,请使用此单行:
for filename in img*jpg; do mv -v $filename $(echo $filename | sed 's/img_/newyears_/'); done
您也可以不使用 sed 来完成:
for filename in img*jpg; do mv -v "$filename" "newyears_${filename#*_}"; done
在 CenotOS 7 中测试
红宝石(1.9+)
$ ruby -e 'Dir["img*jpg"].each{|x|File.rename(x,x.gsub(/img_(.*?)-(.*?)-(.*?)\.jpg/,"newyears_20\\2-\\1-\\3.jpg") )}'
for f in *.jpg; do
n=$(sed -r 's/^(.+)-([^_]+)_(.+)\.jpg/\2-\1_\3.jpg/' <<< "${f#img_}")
mv "$f" "newyears_20$n"
done
<<<
是一个 bash
功能,称为 here string,并且 ${f#img_}
从 img_
中删除 $f
前缀。 sed
表达式通过将 img_MM-DD-YY_XX.jpg
隔离为 YY-MM-DD_XX.jpg
、将 MM-DD
隔离为 \1
、将 YY
隔离为 \2
,然后形成 XX
,将 \3
转换为 \2-\1_\3.jpg
。请注意,n
作业中不需要引用。
为了安全起见,对于这样的事情,我实际上更喜欢使用
echo mv
而不是 mv
,这样我就可以看到它将生成的命令。然后您可以删除 echo
或将输出通过管道传输到 sh
。