練習用に作成したスクリプトは次のとおりです。現在のディレクトリサブツリーですべての一般ファイルを繰り返し検索し、最後の変更日を昨日に変更する必要があります。
#!/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つの日付が作成されます。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を使用すると、全体の練習を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 **
働くでしょう...