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期待どおりに動作しません。私の言葉はそれが私に知らせ、file1ディレクトリfile2内にあることを意味しますa。したがって、touch最後の変更日を変更するために使用すると、昨日の日付file1としてディレクトリに2つの日付が作成されます。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を使用すると、全体の練習を1段階で行うことができるようです。

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

働くでしょう...

関連情報