在 Unix 中重命名文件名

问题描述 投票:0回答:2

我们需要将文件从 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
unix rename ksh
2个回答
0
投票

除非这些文件名全部由八个字符组成,后跟重复三次的

.dat
,否则您最好使用正则表达式来修改它们。像
sed
这样的实用程序可以毫无困难地做到这一点。

您的问题有点不清楚这些

.dat
文件所在的位置,但如果它们都在同一目录中,那么这应该可以工作:

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

0
投票

@r3mainer:您的解决方案是可能的,但其可行性取决于有多少个此类文件:使用 sed (或任何其他外部程序 - awk、tr、...)将需要生成一个完整的新子进程及其环境对系统来说是相当繁重的。幸运的是,您的 sed 脚本的功能可以通过使用“参数替换”在 shell 中实现。

@riva:首先,你的代码无法工作,因为变量赋值中不允许有空格:

 new = "${file:0:12}"    # wrong!
 new="${file:0:12}"      # correct!

即使是第二个也只能根据您正在使用的 shell 来工作。例如 ksh88(AIX 中的默认 shell)不会,ksh93(Linux 中唯一的 ksh 版本,在 AIX 中名为“增强型 Korn shell”)会理解。

不过,@r3mainer 的批评仍然成立:只有当所有文件名都保证为 8 个字符长时,这才有效。相反,您可以使用参数替换来获得您想要的:

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

扩展

${variable%%pattern}
pattern
内容的末尾剪切
variable
(以其最长的可能形式,“贪婪匹配”)。由于模式是“.dat*”,这意味着从第一个(任意多个)“.dat”序列开始的所有内容都会被剪切。然后在末尾添加一个“.dat”。

此外,请注意,您不应该对此类活动使用“for 循环”。 “find”是用于此类目的的命令:

 find /some/directory -type f -name "*.dat" -print |\
 while read FILE ; do
      mv "${FILE}" "${FILE%%.dat*}.dat"
 done
© www.soinside.com 2019 - 2024. All rights reserved.