Regex 使用sed和mv重命名文件
我想以以下格式重命名文件: img_MM-DD-YY_XX.jpg img_MM-DD-YY_XXX.jpg 致: 新年_YYYY-MM-DD _XXX.jpg 其中:Regex 使用sed和mv重命名文件,regex,bash,sed,mv,Regex,Bash,Sed,Mv,我想以以下格式重命名文件: img_MM-DD-YY_XX.jpg img_MM-DD-YY_XXX.jpg 致: 新年_YYYY-MM-DD _XXX.jpg 其中: YYYY=年 毫米=月 DD=天 XXX或XX=照片编号 我想出了这个脚本,但它不起作用: for filename in ?*.jpg; do newFilename=$(echo $filename | \ sed 's/img_\(.*\)-\(.*\)-\(.*\)_\([0-9][0
- YYYY=年
- 毫米=月
- DD=天
- XXX或XX=照片编号
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
任何帮助都将不胜感激。我记得我在这类事情上胡闹过。我发现创建一个脚本来执行您想要的操作通常很有用: 即,脚本的输出将是如下文件:
mv file1 file2
mv file3 file4
.....
mv fileN fileM
要创建它,只需执行ls | grep date pattern | sed脚本,将mv file1粘贴到file2>myscript
然后执行./myscript
通过这种方式,您可以更好地查看中间输出,找出哪里出了问题。这个简单的变体适合我:
$ 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上测试。您可以在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
用于*.jpg中的文件名;做
newFilename=$(sed-E的#img([0-9]{1,2})-([0-9]{1,2})-([0-9]{1,2})$#newyears(sed-E的#img)可以由一个纯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+)
用于*.jpg;do中的f
n=$(sed-r's/^(+)-([^^+)\.jpg/\2-\1\u3.jpg/'不带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管道连接至bash,以查看mv前的结果
多亏了运行脚本时会发生什么?在*.jpg;中文件名的返回了什么?*.echo$filename;done
返回了什么?我发现了问题。删除了管道后面的反斜杠“\”,使其工作。我想在bash脚本中不应转义换行符。这是否正确?反斜杠不是必需的,但应该不会引起任何问题。它后面可能有空格,或者类似的东西吗?您还希望在FreeBSD.Nice上使用-E。如果脚本中有空格,则可以在$filename和$newFilename周围添加双引号值。不解析ls
output@GillesQuenot你可能会给出一个理由,这会很有帮助。似乎太脆弱。需要引用请为你的答案添加解释,以获得长期价值,这样未来的访问者可以从你的解决方案中学习,并将这些知识应用到他们自己的编码问题上。只使用代码的答案是不受欢迎的,而不太喜欢伊利收到了选票。修正了引用,增加了解释。事实上,重写了整件事,因为输出都错了。我想我当时没有测试它。看起来太脆弱了。需要引用看起来太脆弱了。需要引用吗
for f in *.jpg; do
n=$(sed -r 's/^(.+)-([^_]+)_(.+)\.jpg/\2-\1_\3.jpg/' <<< "${f#img_}")
mv "$f" "newyears_20$n"
done
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