Linux Shell脚本重命名
现在我有了如下重命名脚本:Linux Shell脚本重命名,linux,shell,file-rename,batch-rename,Linux,Shell,File Rename,Batch Rename,现在我有了如下重命名脚本: cd /Users/KanZ/Desktop/Project/Test/ n=1 for file in *.jpg; do echo $file prefix=M file_name=M$n.jpg echo $file_name n=$(( $n+1 )) mv $file $file_name done 首先,如果我运行脚本,所有jpg文件都将是M1.jpg M2.jpg M3.jpg,但是如果我将新文
cd /Users/KanZ/Desktop/Project/Test/
n=1
for file in *.jpg; do
echo $file
prefix=M
file_name=M$n.jpg
echo $file_name
n=$(( $n+1 ))
mv $file $file_name
done
首先,如果我运行脚本,所有jpg文件都将是M1.jpg M2.jpg M3.jpg,但是如果我将新文件名A1.jpg添加到此目录并再次运行脚本。所有M1.jpg M2.jpg M3.jpg都将替换为M4.jpg(在运行脚本之前,这个文件名为A1.jpg),因为第一个字母是A。它位于M之前。这是我的问题。我想得到M1 M2 M4.jpg,如果每次有新文件出现,这个脚本将生成类似M5.jpg M6.jpg的continue名称。代码是什么样子的?希望你能理解。感谢您的帮助我理解您的要求是: 将所有.jpg文件名从原来的名称更改为M*.jpg,并在M之后增加一个数字 在程序多次运行期间,计数应从上次运行期间设置的M文件的最高值开始增加。例如,如果程序的第一次运行创建了M1、M2、M3,然后您添加了更多的文件,那么它们应该从M4、M5、M6开始 但M1、M2、M3本身不应改变 因此,有几点建议: 您正在脚本的开头设置n=1。您应该使用上一次运行的文件中存在的最高值Mx.jpg 其次,当您查找文件并对其进行迭代时,请排除所有M*.jpg文件,以便它们的名称不会被替换 你认为这是你的要求吗。如果您有任何其他输入,请添加注释。将在下一条评论中发送脚本 测试用例: 现有文件,X.jpg,ASG.jpg,GER.jpg 运行后的文件名:M1.jpg、M2.jpg、M3.jpg 如果在第一次运行之后再次运行脚本,而没有其他文件:文件名应该没有任何更改:M1.jpg、M2.jpg、M3.jpg 现在添加更多文件:Z.jpg、A.jpg、B.jpg 文件名应更改如下: M1.jpg=>M1.jpg,M2.jpg=>M2.jpg,M3.jpg=>M3.jpg,A.jpg=>M4.jpg,B.jpg=>M5.jpg,Z.jpg=>M6.jpg。
因此,文件名将是M1.jpg、M2.jpg、M3.jpg、M4.jpg、M5.jpg、M6jpg 这个小脚本就可以了
cd /Users/KanZ/Desktop/Project/Test/
n=$(ls -1 | grep '^M' -c) # find the number for M files
ls -1 *.jpg| grep -v '^M' | while read file # for each of the non-M files
do
n=$(($n+1));
new_file=M$n.jpg # new name with next available M file name
mv "$file" "$new_file" # rename with new file name
done
看看它是如何工作的
test/rename$ for x in 1 2 3; do echo A$x> A$x.jpg; done;
test/rename$ ls
A1.jpg A2.jpg A3.jpg
test/rename$ cat ../rnm.sh
#!/bin/bash
cd "$1"
n=$(ls -1 | grep '^M' -c)
nfiles=$(ls -1 *.jpg| grep -v '^M');
for file in $nfiles;
do
n=$(($n+1));
new_file=M$n.jpg
mv $file $new_file
done
test/rename$ bash ../rnm.sh ./
test/rename$ ls
M1.jpg M2.jpg M3.jpg
test/rename$ for x in 1 2 ; do echo B$x> B$x.jpg; done;
test/rename$ ls
B1.jpg B2.jpg M1.jpg M2.jpg M3.jpg
test/rename$ bash ../rnm.sh ./
test/rename$ ls
M1.jpg M2.jpg M3.jpg M4.jpg M5.jpg
test/rename$ for x in *.jpg; do echo $x; cat $x; done;
M1.jpg
A1
M2.jpg
A2
M3.jpg
A3
M4.jpg
B1
M5.jpg
B2
到目前为止给出的其他答案并没有显示出任何良好的实践 这里有一种可能性假设编号是连续的(即,从
M4.jpg
到M6.jpg
)。如果没有这个假设,脚本是安全的(它不会覆盖现有文件,但不会重命名某些文件)
选项至-n
:无缓冲(不要覆盖已存在的文件)mv
选项到-v
:要详细(这样你就不需要你的回声了)mv
事情:选项结束后,只会在后面找到参数(以防某些文件以连字符开头,这会混淆--
)mv
ls-lm*.jpg | wc-l
;n=$($n+1));为ls*.jpg | grep-v“M.*.jpg”中的文件回显$n
;do echo$file prefix=0M file_name=M$n.jpg echo$file_name n=$($n+1))mv$file$file_namedone@gniourf_gniourf解析命令(包括ls)的输出本身并没有什么不好的地方。如果您对解析输出的特定方法效率较低或特别麻烦的原因有建设性的意见,请这样说。不要只说某件事“不好”。侮辱通常不是影响他人的好方法。在for
循环中解析ls
的输出会在文件名包含空格后立即中断。一旦文件名包含换行符,通过另一个命令传输ls的输出就会中断。这些做法真的很糟糕(我希望它们能从互联网上完全消失),特别是因为存在着强大(更有效)的解决方案,例如glob。@kantawit接受答案。:)如果没有M*文件,它将从m1开始,为什么它从M2开始,即使没有M*文件,它也不会。请删除该文件夹中的所有文件,然后重新安装tesstOk,我收到了。再次非常感谢你^_^
#!/bin/bash
shopt -s extglob
shopt -s nullglob
cd /Users/KanZ/Desktop/Project/Test/
# Determine how many files MX.jpg you have (with X a number):
files=( M+([[:digit:]]).jpg )
n=${#files[@]}
for file in !(M+([[:digit:]])).jpg; do
file_name=M$((++n)).jpg
mv -vn -- "$file" "$file_name"
done