简体   繁体   English

使用 sed 和 mv 重命名文件

[英]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:在哪里:

  • YYYY = year YYYY = 年
  • MM = month MM = 月
  • DD = day DD = 天
  • XXX or XX = photo number XXX 或 XX = 照片编号

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隔离为\\1YY\\2XX\\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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM