在Unix中重命名文件名

oxalkeyp  于 7个月前  发布在  Unix
关注(0)|答案(2)|浏览(190)

我们需要将文件从 filename.dat. dat.dat 重命名为 filename.dat。我们有很多文件具有相同类型的名称,扩展名为 .dat. dat.dat
使用下面的脚本:

cd /home/riya
for file in filename.dat.dat.dat
do
    echo $file
    new = "${file:0:12}"
    echo $new
    mv $file $new
done

字符串
给出以下错误:

riya.ksh[5]: "${file:0:12}": bad substitution

plupiseo

plupiseo1#

除非这些文件名都由8个字符组成,后面跟着重复三次的.dat,否则你最好使用正则表达式来修改它们。像sed这样的实用程序可以毫不费力地做到这一点。
你的问题有点不清楚这些.dat文件位于何处,但如果它们都在同一个目录中,那么这应该可以工作:

for f in *.dat.dat.dat
  do
    g=$(echo $f | sed s/\\.dat\\.dat//)
    echo "$f -> $g" ; mv $f $g
  done

字符串

oiopk7p5

oiopk7p52#

r3 mainer的解决方案是可行的,但其可行性取决于有多少这样的文件:使用sed(或任何其他外部程序-AWKtr,...)将需要产生一个完整的新子进程及其环境,这对系统来说是相当繁重的。
幸运的是,sed脚本的功能可以通过使用“参数替换”在shell中实现。
@riva:首先,你的代码不能工作,因为变量赋值不允许有空格:

new = "${file:0:12}"    # Wrong!
 new="${file:0:12}"      # Correct!

字符串
即使是第二个也只能工作,这取决于您使用的是哪种shell。例如,ksh 88(AIX中的默认shell)不能工作,ksh 93(Linux中唯一的KornShell版本,在AIX中命名为“增强的Korn shell”)可以理解这一点。
尽管如此,@r3mainer的批评仍然成立:只有当所有文件名都保证是八个字符长时,这才有效。相反,你可以使用参数替换来获得你想要的:

new="filename.dat.dat.dat"
 echo ${new%%.dat*}          # This will yield "filename"
 new="${new%%.dat*}.dat"     # This will yield "filename.dat"


扩展${variable%%pattern}variable的内容的末尾剪切pattern(以其最长的可能形式,“贪婪匹配”)。由于模式是“.dat*",这意味着从第一个(任意多个)“.dat”序列开始的所有内容都被剪切。然后在末尾添加一个“.dat”。
另外,请注意,您不应该为这种活动使用 for 循环。find是用于这种目的的命令:

find /some/directory -type f -name "*.dat" -print |\
 while read FILE ; do
      mv "${FILE}" "${FILE%%.dat*}.dat"
 done

相关问题