这是我为练习而编写的脚本。它应该递归地查找当前目录子树中的所有常规文件,并将最后修改日期更改为昨天的日期。
#!/bin/bash
YESTERDAY=$(date -d yesterday)
RFILES=$(ls -lR | egrep '^-' | rev | cut -d" " -f1 | rev)
for i in $RFILES ; do
ABSPATH=$(readlink -f $i)
touch "$ABSPATH" -d "$YESTERDAY"
done
如果我在具有如下子树的目录中调用它:
a
|___ b
| |__ file1
| |__ file2
|
|__ file3
|__ file4
readlink
没有按预期工作。我的意思是它告诉我file1
和file2
位于目录内a
。因此,当我用来touch
更改他们的最后修改日期时,它会在目录中file1
再创建两个具有昨天日期的日期。file2
a
答案1
首先,命令ls -lR | egrep '^-' | rev | cut -d" " -f1 | rev
只显示文件名,不显示路径。如果您需要获取带有路径的所有文件,您可以使用find ./ -type f
并解析该输出。因此readlink -f $i
命令将是不必要的。
其次,如果你需要更有效的解决方案,你只需要find
带参数的命令exec
:
find . -type f -exec touch -d "$YESTERDAY" {} +
-type f find regular files
答案2
readlink 程序用于读取符号链接的位置,如果您只有常规文件,可能有更好的工具可以完成这项工作。为了查找文件,我喜欢使用find
命令。看来您可以使用 find 一步完成整个练习:
find . -type f -exec touch {} -d "$(date -d yesterday)" \;
find .
:搜索当前目录.
及其下的所有内容-type f
:仅搜索常规文件-exec
:告诉 find 对找到的每个对象运行以下命令touch {} -d "$(date -d yesterday)" \;
:您要对每个文件执行的命令。 “{}”是输出的占位符find
和 \;指定-exec
语句的结束
答案3
您的 RFILES 只是没有路径的文件名。readlink
不是find
,它使用您给它的名称,并且其中没有路径,则假定它们位于当前目录中。
使用现代 bash:
shopt -s globstar
RFILES=( ** )
但你不需要readlink
你可以直接使用输出ls
。就globstar
这么简单:
touch -d "$YESTERDAY" $(ls -d **)
实际上你甚至不需要ls
:
touch -d "$YESTERDAY" **
否则与find
:
find . -type f -exec touch -d "$YESTERDAY" {} +
最后,日期规范touch
比您想象的更灵活:
touch -d yesterday **
将工作...