我有一个编号的文件列表,如下所示:
01_file_name.log
01_file_name.txt
02_file_name.log
02_file_name.txt
03_file_name.log
03_file_name.txt
04_file_name.log
04_file_name.txt
05_file_name.log
05_file_name.txt
我想为所有03*
和文件插入新04*
文件。因此,从编号03
开始,所有文件都需要移动/重命名,其前导编号增加 2,因此列表如下所示:
01_file_name.log
01_file_name.txt
02_file_name.log
02_file_name.txt
05_file_name.log
05_file_name.txt
06_file_name.log
06_file_name.txt
07_file_name.log
07_file_name.txt
我在想类似的东西:
bash script.sh 03 02
而03
on$1
是文件名的开头编号和要添加的编号02
。$2
我试图通过嵌套来实现这一点,for-loop
但我不得不放弃使用计数器的组合((++))
来使循环仅通过病房中给定编号的文件运行。
这可以满足您的需求。一件事:我认为它只适用于 BASH。
MAXDIGITS
是可选的,我把它放在那里以防您需要使用三位数或更多位数。如果你不使用它,删除相应的行。要使用它:
如果您在同一目录中有其他文件不符合相同的语法(prefix_filename.{txt,log}),则必须过滤它们。另外,我使用“_”将前缀与文件名分开,所以如果你改变它,你需要修复代码。
值得一提的是,这是一个包含两个过程替换和一个非常简单的过程
bash
的单行代码:awk
解释:
上面的一行是从右到左阅读或至少“理解”的。
ls -r -1 *_file_name.{log,txt}
以一列格式以相反的顺序列出要处理的所有文件。请注意,如果文件前缀(由 表示
*
)包含非数字字符,您可能会得到无法预料/不需要的结果。为防止这种情况,请在此阶段过滤要处理的文件。<(...)
过程替代。它允许使用文件描述符引用先前的结果输出,即称为命名管道的特殊临时文件。有关man bash
终端中的详细信息问题。awk
脚本:BEGIN{FS="_"}
在开始处理记录之前,将记录的字段分隔符设置为“_”(awk 的第一个块)awk
的第二个块的条件,$1>2
: 只处理文件名前缀严格大于 2 的记录prefix=$1+2
定义 awk 的“前缀”内部变量。使其在数值上等于前缀$1
+ 2printf("my_format",var1,var2,...)
打印格式化命令,以新行分隔。请注意,格式化涉及%0.2d
,即awk
在必要时将 的变量“前缀”打印为带有 0 填充的两位数。输出是:mv -f 05_file_name.log 07_file_name.log
mv -f 05_file_name.txt 07_file_name.txt
mv -f 04_file_name.log 06_file_name.log
mv -f 04_file_name.txt 06_file_name.txt
mv -f 03_file_name.log 05_file_name.log
mv -f 03_file_name.txt 05_file_name.txt
mv -f ...
命令。如果您想知道为什么重复使用入站或出站进程替换(不是 POSIX 的东西!)
bash
是有利的,请参阅此示例。最后说明:
在上述单行代码中包含运行时参数并将其封装在可执行的 shell 脚本中很容易,从定义开始
VAR1
并VAR2
分配给awk
's 过程:在可执行脚本中,
script.sh
:其中
VAR1
并VAR2
具有 OP 中定义的含义。如果您需要在生产环境中使用该脚本,我强烈建议您添加一些检查和故障保险,以确保您的输入文件和变量的值始终是预期的。@MarceloCastro 的脚本很好,即使它基于
for
循环,我倾向于尽可能避免。for
循环往往很慢,如果您处理大量文件,您可能会注意到这一点。我制作了符合您目标的脚本。
与
zsh
:然后删除
-n
(用于试运行)以实际执行。zmv pattern replacement
:zmv
是一个可自动加载的函数,它利用强大的 zsh glob 和扩展运算符来进行复杂的文件重命名。<x-y>
匹配十进制数 x 到 y。(#q...)
全局限定符nOn
: ame 的n
rdero
(大写 O 颠倒)n
。由于我们正在增加数字,因此05...
将在此处根据需要出现。04...
${(l:n::padding:)expansion}
:l
eft使用padding将扩展填充到长度n。所以用, 左填充到长度为 2 和 0。${(l:2::0:)}
$(($1+2))
,第一个捕获的组增加 2。$2
:第二个捕获组:前导数之后是什么。