脚本中可能有各种故障点。首先,rm *.old*
将使用globbing创建所有匹配文件的列表,并且可以处理包含空格的文件名。但是,您的脚本会为glob的每个结果分配一个变量,并且无需引用即可执行该操作。如果您的文件名包含空格,那将会中断。例如:
$ ls
'file name with spaces.old.txt' file.old.txt
$ rm *.old.* ## works: both files are deleted
$ touch "file.old.txt" "file name with spaces.old.txt"
$ for i in ./*; do oldfile=$i; rm -v $oldfile; done
rm: cannot remove './file': No such file or directory
rm: cannot remove 'name': No such file or directory
rm: cannot remove 'with': No such file or directory
rm: cannot remove 'spaces.old.txt': No such file or directory
removed './file.old.txt'
如您所见,文件名中带有空格的循环失败。要正确执行此操作,您需要引用该变量:
$ for i in ./*; do oldfile="$i"; rm -v "$oldfile"; done
removed './file name with spaces.old.txt'
removed './file.old.txt'
相同的问题适用$i
于脚本中几乎所有的用法。您应该始终引用变量。
下一个可能的问题是,您似乎期望*.old.*
与扩展名为的文件匹配.old
。没有。它匹配“ 0个或多个字符”(*
),然后是.
,然后是“旧”,然后是另一个.
,然后又是“ 0个或多个字符”。这意味着它将不会匹配file.old
,而只会匹配`file.old.foo:
$ ls
file.old file.old.foo
$ for i in *; do if [[ "$i" == *.old.* ]]; then echo $i; fi; done
file.old.foo
因此,没有对手file.old
。无论如何,您的脚本都比需要的复杂得多。尝试以下一项:
#!/bin/bash
for i in *; do
if [[ -f "$i" ]]; then
if [[ "$i" == *.old ]]; then
rm -v "$i" || echo "rm failed for $i"
else
echo "$i doesn't have an .old extension"
fi
cp -v "$i" "$i".old
else
echo "$i is not a file"
fi
done
请注意,我-v
在rm
和cp which does the same thing as what you were doing with your
echo`语句中添加了内容。
这不是完美的,因为例如当您找到时,file.old
它将被删除,并且此脚本以后将尝试复制它,并且由于文件不再存在而失败。但是,您还没有解释脚本实际上试图执行的操作,因此除非您告诉我们您真正想要完成的操作,否则我无法为您解决该问题。
如果您要i)删除所有带有.old
扩展名的文件,并且ii)将.old
扩展名添加到没有扩展名的任何现有文件中,那么您真正需要的是:
#!/bin/bash
for i in *.old; do
if [[ -f "$i" ]]; then
rm -v "$i" || echo "rm failed for $i"
else
echo "$i is not a file"
fi
done
## All the ,old files have been removed at this point
## copy the rest
for i in *; do
if [[ -f "$i" ]]; then
## the -v makes cp report copied files
cp -v "$i" "$i".old
fi
done
rm *.old.*
都删除。在命令行上,我使用它删除了这些文件但不是file.old备份文件。我正在尝试在脚本中执行此操作。谢谢