用条件检查目录名的Bash脚本

  • 本文关键字:Bash 脚本 条件 linux bash
  • 更新时间 :
  • 英文 :


我想排除一些目录在我的脚本(目录名>1000)删除,这里是我的目录看起来像:

/home/tester/100
/home/tester/1000
/home/tester/1020  # delete all files inside
/home/tester/2000  # delete all files inside
我的bash脚本:
cd /home/tester
for dir in */ ; do
echo -n $dir": ";
find "$dir" -type f | wc -l;
if [ $dir -gt 1000 ]; then
cd $dir;
rm *;
cd ..;
fi
done

我在if行上出错了,不知道如何修复它…可以用bash脚本吗?

谢谢你的帮助

for dir in */ ; dodir设置为"1000/"——和"/"使得它不是一个有效的数字。你可以修剪掉后面的"/"用${dir%/}。我还建议双引号,以防止可能的奇怪解析:

if [ "${dir%/}" -gt 1000 ]; then

请注意,如果目录名不是数字(即使在"/"之后)),您将从比较中得到一个错误,并且then子句不会运行(这可能是您想要的)。如果您想更优雅地处理其他(非数字)目录名,您应该首先添加一些适当的is-this-a-number测试。

此外,在脚本中使用cd往往是有问题的,因为如果cd由于任何原因失败,脚本的其余部分将继续运行,但在错误的位置。这会导致各种各样的混乱。考虑一下如果其中一个cd $dir命令失败会发生什么:它会在/home/tester目录中运行rm *,删除那里的所有非子目录文件,然后运行cd ..,将其留在/home中。下一次迭代将尝试将cd降至2000之类的值,这在/home下不存在,因此cd也会失败,然后它将删除/home中的所有文件。这个过程无限地重复,可能一直到在根目录/中运行rm *。一点也不好。

我建议对cd命令进行错误检查,或者完全避免错误检查,以便使用显式的文件路径。

#!/bin/bash
cd /home/tester || {
echo "Couldn't cd to /home/tester, quitting here..." >&2
exit 1
}
for dir in */ ; do
echo -n "$dir: "
find "$dir" -type f | wc -l
if [ "${dir%/}" -gt 1000 ]; then
rm "$dir"/*    # Explicit path -- the / is redundant, but won't hurt
fi
done

我还添加了显式shebang行,将所有变量引用双引号(良好的通用脚本卫生),并从行末删除分号(在shell语法中不需要)。

另一个建议:通过shellcheck.net运行脚本——它会指出许多常见的错误,如未加引号的变量引用和未检查的cds。

$dir的值不是数字。在脚本末尾添加set -x以进行调试。

使用"$(basename "$dir")"获取数值

当我没有喝第一杯咖啡时,我会做

for dir in */ ; do
echo -n $dir": ";
find "$dir" -type f | wc -l;
done
mv /home/tester/1000 /home/tester/some_unique_name
rm /home/tester/[1-9][0-9][0-9][0-9]/*  
mv /home/tester/some_unique_name /home/tester/1000

当你有目录>9999.
也许rm /home/tester/[1-9][0-9][0-9][0-9]*/*可以工作,当你没有1000backup2000my_unique_name这样的目录。

一个更好的解决方案是

find . -regextype sed -regex '/home/tester/[0-9]{4,}' ! -name 1000 | 
xargs -L1 -I{} echo rm {}/* 

最新更新