Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux Shell脚本重命名_Linux_Shell_File Rename_Batch Rename - Fatal编程技术网

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

您的脚本看起来很糟糕;我想你在这里复制粘贴的时候出了点问题。特别是,它似乎遗漏了一些必要的换行符。检查是的,所有你认为正确的东西!!谢谢你理解我,帮助我。你能给我一个代码吗,因为我不懂如何编写shell脚本。n=
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