Bash 如何使用多个规则创建重命名脚本?

Bash 如何使用多个规则创建重命名脚本?,bash,rename,Bash,Rename,我经常把一堆名为Unknown.png的文件放进一个文件夹,经常会将它们重命名为Unknown 1.png、Unknown 2.png等。这是一个小问题,因为有时在清理文件并将其移动到其他地方时,会有人问我是否要替换或重命名,等等 所以我决定做一个crontab任务,将文件重命名为CB_RANDOM,这样我就不用担心可能会覆盖两个同名文件 到目前为止,我可以找到这些文件,替换CB_u未知的名称,并添加一个随机数 问题出现在文件名末尾的x处。我也设法解决了这个问题,我去掉了括号和数字 问题是我不知

我经常把一堆名为Unknown.png的文件放进一个文件夹,经常会将它们重命名为Unknown 1.png、Unknown 2.png等。这是一个小问题,因为有时在清理文件并将其移动到其他地方时,会有人问我是否要替换或重命名,等等

所以我决定做一个crontab任务,将文件重命名为CB_RANDOM,这样我就不用担心可能会覆盖两个同名文件

到目前为止,我可以找到这些文件,替换CB_u未知的名称,并添加一个随机数

问题出现在文件名末尾的x处。我也设法解决了这个问题,我去掉了括号和数字

问题是我不知道如何使重命名函数同时遵循这两个规则

for u in (find -name unknown*); do 
    rCode = random
    rename -v 's/unknown/CB_$rCode' $u 
    rename -v 's/[ ()0123456789]//g' $u

理想情况下,我希望能够在同一行代码上遵循这两条规则,特别是因为一旦它运行第一行,$u将无法找到第二步的文件。

您的代码应首先更改为

# find is a subcommand, use $()
# find a file with wildcard, use quotes
for u in $(find -name "unknown*"); do 
    # Is random a command? Use $()
    rCode=$(random) 
    # Debug with echo, will show other problem
    echo "File $u"
    # $rCode will not be replaced by its value in single quotes
    # Write a filename in double quotes, so it will not be split by a space
    rename -v "s/unknown/CB_$rCode" "$u"
    rename -v 's/[ ()0123456789]//g' "$u"
done
带有echo的新行显示循环正在拆分空格处的文件名。你可以改变这个

while IFS= read -r u; do 
    # Use unique timestamp, not random value
    rCode=$(date '+%Y%m%d_%H%M') 
    echo "File $u"
    rename -v "s/unknown/CB_$rCode" "$u"
    rename -v 's/[ ()0123456789]//g' "$u"
done < <(find -name "unknown*")
编辑: 我删除了一个用于重命名文件的sed命令,其中包含以下内容:

不需要循环:

find -name 'unknown*' -exec rename 's/unknown \([0-9]+\)\.(.*)$/"CB_".sprintf("%04s",int(rand(10000))).".".$1/e' {} \;
从当前目录开始,以递归方式查找名称类似于unknown 1.png的所有文件 使用类似于CB_0135.png的结果文件名重命名它们
如果文件名已存在,则会生成错误消息。

重命名整个文件名而不是未知部分可以解决此问题。重命名-v${u}CB_${rCode}.png${u}因为您使用的是循环,所以可以使用bash语法构造新名称并使用mv。如果您想使用模式规则重命名文件夹中的文件,那么重命名就是要使用的工具。非常感谢您提供如此详细的响应,我一直在研究代码以了解每一行的作用抱歉,我在这方面有点新,但我正在尝试!首先,我会注意到您在一段时间内替换了FOR循环,并在最后添加了find命令,这是否仍然使其仅将这些更改应用于名为unknown*的文件?代码中似乎不起作用的部分是剥离x,因为我得到的文件名类似于unknown 193145_x.png,它也不适用于unknown.png文件,看起来它需要文件名上有一个x才能工作。我编辑了我的答案,但您应该更喜欢@DennisWilliamson的解决方案。我将FOR替换为WHILE,将文件名替换为空格,并将查找移动到末尾,使其在不使用额外子shell的情况下运行。此处不相关,但子shell中循环中设置的变量将在循环完成时丢失。这是一个很好的命令,虽然它只在末尾添加文件名时起作用,但它似乎不会对找到的每个文件都运行rename命令。“你知道我们怎样才能解决这个问题吗?”丹尼洛雷耶斯:恐怕我没有理解你的意思。此命令查找所有以unknown开头的文件,然后如果匹配的模式在括号中有一个数字并且有任何扩展名,则重命名这些文件。当然,模式可以改变。但是在末尾添加文件名不应该做任何事情,或者会产生错误。这个命令按原样为我工作。你修改了吗?如果是,怎么做?你的操作系统是什么?我使用的是Ubuntu,如果我把代码按原样粘贴在终端上,它不会重命名任何文件。就我个人而言,我一直在努力使find-exec命令即使在其他发行版中也能正常工作。基本上,我让它工作的方法是删除find部分,并在最后手动添加文件名。如果我删除-exec部分,它似乎实际上列出了所有文件。但这两个命令在某种程度上无法协同工作。我试着把它放在一个循环中,然后通过你给我的重命名行输入文件,但它要么在文件名中添加一个./要么在x处裁剪它。在对代码进行了大量的修改后,我试图完全理解每个片段的工作原理,我找到了如何使其工作的方法。我只需从s/^unknown中删除^s,然后它重命名了任何未知的x.png文件,对于原始的unknown.png文件,我可以修改现有代码使其工作,我认为这一切都很好!非常感谢你!虽然我很好奇这是什么意思?因为我觉得奇怪的是,如果我单独使用rename命令,它就可以工作,但是在使用find命令时失败了。@DaniloReyes:啊!对不起!插入符号()将正则表达式锚定在字符串的开头,但我没有考虑到find在其输出中包含文件的路径这一事实。在本例中,它是当前目录。/。我将删除我答案中的插入符号。但是,请注意,如果没有它,名称为complete unknown 1.png的文件将匹配并重命名。可以使用斜线作为锚,我可以添加一个替代方案来显示这一点。
# Removed command
    newfile=$(sed 's/\(.*\)(\(.*\))/\1'"${rCode}"'_\2/' <<< "$u")
find -name 'unknown*' -exec rename 's/unknown \([0-9]+\)\.(.*)$/"CB_".sprintf("%04s",int(rand(10000))).".".$1/e' {} \;