readlink -f 未按预期工作

readlink -f 未按预期工作

这是我为练习而编写的脚本。它应该递归地查找当前目录子树中的所有常规文件,并将最后修改日期更改为昨天的日期。

#!/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没有按预期工作。我的意思是它告诉我file1file2位于目录内a。因此,当我用来touch更改他们的最后修改日期时,它会在目录中file1再创建两个具有昨天日期的日期。file2a

答案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 **

将工作...

相关内容