[英]Rename files using sed and mv
I want to rename files in the format:我想重命名以下格式的文件:
img_MM-DD-YY_XX.jpg img_MM-DD-YY_XX.jpg
img_MM-DD-YY_XXX.jpg img_MM-DD-YY_XXX.jpg
to:到:
newyears_YYYY-MM-DD_XXX.jpg newyears_YYYY-MM-DD_XXX.jpg
Where:在哪里:
I came up with this script but it isn't working:我想出了这个脚本,但它不起作用:
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
Any help would be greatly appreciated.任何帮助将不胜感激。
You can try this script in bash:你可以在 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
is supported by gnu sed
also. gnu sed
也支持sed -E
。
Without a for loop.没有 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
Ommit piping to bash to see the results before mv在 mv 之前省略管道到 bash 以查看结果
Thanks to http://www.gnu.org/software/sed/manual/sed.html#Rename-files-to-lower-case感谢http://www.gnu.org/software/sed/manual/sed.html#Rename-files-to-lower-case
I remember messing around with this sort of thing.我记得我在搞这种事情。 I found it often useful to create a script that you execute to do what you want:我发现创建一个脚本来执行您想要的操作通常很有用:
ie. IE。 output of your script would be a file like:脚本的输出将是一个文件,如:
mv file1 file2
mv file3 file4
.....
mv fileN fileM
To create this, just do a ls |要创建它,只需执行 ls | grep date pattern | grep日期模式| sed script to stick mv file1 to file2 > myscript sed脚本将 mv file1 粘贴到 file2 > myscript
then just execute ./myscript然后执行 ./myscript
This way you have a better look at the intermediate output to figure out what's going wrong.通过这种方式,您可以更好地查看中间输出以找出问题所在。
This trivial variant works for me:这个微不足道的变体对我有用:
$ 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
$
The only difference is the use of the explicit -e
options in place of a semi-colon.唯一的区别是使用显式-e
选项代替分号。
Tested on MacOS X 10.6.7.在 MacOS X 10.6.7 上测试。
It could be handled by a purely bash script.它可以由纯粹的 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
红宝石(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
The <<<
is a bash
feature called a here string and ${f#img_}
removes the img_
prefix from $f
. <<<
是一种称为here 字符串的bash
功能, ${f#img_}
从$f
删除了img_
前缀。 The sed
expression turns img_MM-DD-YY_XX.jpg
into YY-MM-DD_XX.jpg
by isolating MM-DD
into \\1
, YY
into \\2
and XX
into \\3
then forming \\2-\\1_\\3.jpg
. sed
表达式将img_MM-DD-YY_XX.jpg
转换为YY-MM-DD_XX.jpg
是将MM-DD
隔离为\\1
, YY
为\\2
, XX
为\\3
然后形成\\2-\\1_\\3.jpg
。 Note that no quoting is required in the n
assignment.请注意,在n
赋值中不需要引用。
For safety, for things like this I actually prefer to use echo mv
instead of mv
, so I can see the command this would generate.为了安全起见,对于这样的事情,我实际上更喜欢使用echo mv
而不是mv
,因此我可以看到这将生成的命令。 Then you can remove echo
or pipe the output to sh
.然后您可以删除echo
或将输出通过管道传输到sh
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.