日期:2014-05-16  浏览次数:20764 次

在Linux下怎么一次性删除掉那些修改时间为指定日期的所有文件?

问:在Linux下怎么一次性删除掉那些修改时间为指定日期的所有文件?

?

答:脚本del_files_of_date.sh

用法:./del_files_of_date.sh <YYYY-mm-dd> <files...>

比如:./del_files_of_date.sh 2011-09-01 html/*.html

#!/bin/sh

: ${2?"usage: $0 <YYYY-mm-dd> <files...>"}

for f in "${@:2}"
do
        modify_time=$(stat --printf '%y' "$f")
        if [[ $modify_time == $1* ]]; then
                echo "$f" "$modify_time"
                rm -v -- "$f"
        fi
done

?

下面是此脚本的一次执行示例

[root@jfht contents]# ./del_files_of_date.sh 2011-08-01 html/*.html
html/0041bb66458751c989fe55d8dd837458.html 2011-08-01 08:55:58.000000000 +0800
已删除“html/0041bb66458751c989fe55d8dd837458.html”
html/05602e464e720e482fe0a33ac71198ea.html 2011-08-01 12:55:33.000000000 +0800
已删除“html/05602e464e720e482fe0a33ac71198ea.html”
……
……
html/ff4dd248f7f6b97bc07519d561d47111.html 2011-08-01 18:55:37.000000000 +0800
已删除“html/ff4dd248f7f6b97bc07519d561d47111.html”
[root@jfht contents]#

?

下面详细解释此脚本

?

第3行:: ${2?"usage: $0 <YYYY-mm-dd> <files...>"}

?

内建命令:(冒号),用来做参数扩展。如果没有,那么就会把后面${2...}的结果当做命令来执行。

man : 写道
: [arguments]
???? No effect; the command does nothing beyond expanding arguments and performing any specified redirec-
tions. A zero exit code is returned.

?

[root@jfht contents]# touch 1.txt
[root@jfht contents]# ./del_files_of_date.sh 2011-09-01 1.txt
./del_files_of_date.sh: line 3: 1.txt: command not found

上面这行是没有在前面增加:命令的执行效果。
1.txt 2011-09-01 19:56:46.000000000 +0800
[root@jfht contents]#

?

(关于:命令的更多信息,参见“我使用过的Linux命令之:(冒号) - 啥也不做(除了……) ”)

?

第3行:: ${2?"usage: $0 <YYYY-mm-dd> <files...>"}

?

${VAR?STRING}的作用是判断变量VAR是否为空,如果为空则打印STRING指定的信息后退出。

这很适合用来检查是否提供了足够多的命令行参数或者变量是否设置,如果为否,打印使用帮助退出。

其中,?前的2,表示是第二个命令行参数。即第二个命令行参数没有设置,就打印帮助信息退出。

?

[root@jfht contents]# ./del_files_of_date.sh
./del_files_of_date.sh: line 3: 2: usage: ./del_files_of_date.sh <YYYY-mm-dd> <files...>
[root@jfht contents]# ./del_files_of_date.sh 2011-09-01
./del_files_of_date.sh: line 3: 2: usage: ./del_files_of_date.sh <YYYY-mm-dd> <files...>
[root@jfht contents]#

?

第5行:for f in ${@:2}

?

在Bash中for结构的写法

for VAR in LIST

do

??? DO_SOMETHING_OF_VAR

done

?

(关于 for 语句的更多信息,参见“我使用过的Linux命令之for - Bash中的For循环 ”)

?

第5行:for f in "${@:2}"

?

关于 ${@:2},其中 @ 是代表所有命令行参数,2表示从第二个参数开始的所有参数。

更通用的情况:${@:START:N},表示从第START个参数开始,截取N个参数。

?

要注意的是${@:2}必须写在双引号里面。

如果去掉双引号,将不能正确处理带有空格的文件名,如下所示:

?

[root@jfht contents]# ./del_files_of_date.sh 2011-09-03 'hello world.txt'
stat: 无法 stat “hello”: 没有那个文件或目录
stat: 无法 stat “world.txt”: 没有那个文件或目录

以空格分隔成文件名,显然不是期望的结果。
[root@jfht contents]#

?

加上双引号的处理情况:

[root@jfht contents]# ./del_files_of_date.sh 2011-09-03 'hello world.txt'
stat: 无法 stat “hello world.txt”: 没有那个文件或目录
[root@jfht contents]#

?

第7行:modify_time=$(stat --printf '%y' "$f")