File 我有大量的文件,我想用越来越多的数字和don';似乎没有重命名功能

File 我有大量的文件,我想用越来越多的数字和don';似乎没有重命名功能,file,sed,renaming,File,Sed,Renaming,我一直在仔细研究,发现了“重命名”和“sed”,我不是很精通计算机,但我已经尝试了我所发现的东西。 到目前为止,我能够使用sed找到我想要搜索的内容,但我无法找到如何替换为我实际寻找的内容(希望这是有意义的) 因此,情况如下: 我有3批5000个文件(2000、2000和1000),生成它们的程序总是从1-x开始编号,所以时间步长1。。。 我需要文件是连续的(所以不是从1开始的批) 我试过: ls time\u step\u124; sed's/[0-9]\(.*)/mv&time\u step

我一直在仔细研究,发现了“重命名”和“sed”,我不是很精通计算机,但我已经尝试了我所发现的东西。 到目前为止,我能够使用sed找到我想要搜索的内容,但我无法找到如何替换为我实际寻找的内容(希望这是有意义的)

因此,情况如下: 我有3批5000个文件(2000、2000和1000),生成它们的程序总是从1-x开始编号,所以时间步长1。。。 我需要文件是连续的(所以不是从1开始的批)

我试过:
ls time\u step\u124; sed's/[0-9]\(.*)/mv&time\u step\u1+2001/'
它还印刷了:

time_step_mv 10.txt time_step_0.txt+2001
time_step_mv 11.txt time_step_1.txt+2001
time_step_mv 12.txt time_step_2.txt+2001
time_step_mv 13.txt time_step_3.txt+2001
time_step_mv 14.txt time_step_4.txt+2001
time_step_mv 15.txt time_step_5.txt+2001
time_step_mv 1.txt time_step_.txt+2001
time_step_mv 2.txt time_step_.txt+2001
time_step_mv 3.txt time_step_.txt+2001
time_step_mv 4.txt time_step_.txt+2001
time_step_mv 5.txt time_step_.txt+2001
time_step_mv 6.txt time_step_.txt+2001
time_step_mv 7.txt time_step_.txt+2001
time_step_mv 8.txt time_step_.txt+2001
time_step_mv 9.txt time_step_.txt+2001
但是文件名本身没有改变 我已经多次管理相同的输出

我想我了解管道和“保存”字符等,但正如我所说的,我不太精通计算机,而且我对我读过的各种帖子中的术语感到困惑


非常感谢所有的帮助

这对第二批有效,然后对第三批有效+3000

for f in time_step_*; do 
   n=${f%.*}; n=${n##*_}; ((n+=2000));
   mv "$f" time_step_$n.txt
done
所以

首先,让我指向BashWiki中的页面。它强调了信任
ls
命令输出的危险。这并不是说你不应该这样做,但你只有在意识到危险的情况下才应该这样做。:)

一些基本的事情:

  • sed
    不是一种编程语言,它不知道如何做数学
  • 在正则表达式中匹配的任何内容都需要在输出中进行说明,即使是表达式开头和结尾的“隐含”内容。这就是为什么输出字符串中嵌入了
    mv
你说:

 ls time_step_* | sed 's/[0-9]\(.*\)/mv & time_step_\1+2001/'
这样做的效果是采用类似于
time\u step\u 12.txt的文件名,并仅用替换字符串替换
12.txt
。尽管sed不能做数学运算,但您真正想在这里使用的正则表达式已经解释了所有输入文本。例如,在bash中:

 ls time_step_* | sed -r 's/^(.*_)([0-9]+)(.*)/mv & \1\2\3/'
结果是一组命令,您可以通过将
|sh
添加到行的末尾,在验证命令是否正确后执行这些命令,从而通过sh(或bash)传递这些命令。注意
-r
选项,在许多实现中,它告诉sed将regex解释为ERE而不是BRE。如果这对您不起作用(因为您使用的是较旧的unix、SVR4等),请这样说,我们可以将正则表达式转换为BRE

我要指出,这不是解决这个问题的好方法,最显著的原因是,正如我所说的,sed不做数学。如果您想向文件名的一个组件添加一个整数,那么您需要使用一些做数学运算的东西来处理它。像巴什

您可以使用sed提取部分数据,然后在一个简单的
循环中处理它,而
循环:

for file in time_step_*.txt; do
  number=${file%.txt}          # strip off the suffix
  number=${number#time_step_}  # strip off the prefix
  if [[ $number -gt 0 ]]; then
    mv "$file" "time_step_$[number+2000].txt"
  else
    echo "ERROR: $file couldn't be processed" >&2
  fi
done
这样做的好处是,除了在shell内部执行
mv
之外,其他操作都可以完成,因此不会启动不必要的外部进程。当然,您的sed管道不会造成太多问题。如果您想(记住上面的ParsingLS链接),可以使用sed减少bash模式匹配,使其可移植到非bash shell。如果不进行错误检查,它可能如下所示:

ls time_step_*.txt | sed -r 's/^(.*_)([0-9]+)(.*)/\2 &/' | while read number file; do
  mv "$file" "time_step_$((number+2000)).txt"
done
这是通过将文件名(如
time\u step\u 12.txt
转换为字符串(如
12 time\u step\u 12.txt
)来实现的,这样就可以通过
while
将两个单独的单词读入单独的变量中。请注意,如果数字不是纯数字,则会出现故障


希望这是教育性的。:-)

这些文件都在同一个目录中吗?或者在一个目录中有2000个文件,在另一个目录中有2000个文件,在第三个目录中有1000个文件?它们都在不同的目录中,第一个目录中的2000个文件很好,接下来的3000个文件是我想要更改的-也就是说,程序在Windows中运行,我只是将它转移到Linux中,因此,它可以被安排。考虑在“代码> > $f”/<代码>中添加双引号。“为了安全起见,清理了一点。谢谢你的建议,这很有效。多好的回答啊!感谢您对正在做的事情及其功能的所有描述-这当然解释了为什么我与sed和grep的一些笨拙尝试在过去可能不起作用。。。我不知道你所说的ERE和BRE是什么意思,但是你上面介绍的代码很有效(所以我认为这意味着我在ERE)。谢谢,很高兴它很有用!BRE和ERE是“基本”和“扩展”正则表达式。在任何unix系统(包括OSX)上,您都应该能够运行以了解这两个方面。