特定の日付に生成されたファイルを見つけるように設計されたBashスクリプトがあります。仕組みは次のとおりです。
#!/bin/bash
LOCATION="/tmp/testfiles"
DATE="Jan 10"
COMMAND="ls -l ${LOCATION} | grep '${DATE}'"
for FILE in `eval $COMMAND`
do
echo $FILE
done
私が期待していたファイルを探しています。
-rw-rw-rw- 1 root root 9485 Jan 10 10:00 test01.log
しかし、bash for ループは ls -l コマンドのすべてのフィールドを繰り返すので、次のように終了します。
-rw-rw-rw-
1
root
root
9485
Jan
10
10:00
test01.log
これが私が望んでいないことです。すべてのフィールドが繰り返されるのを防ぐために、ls -lコマンドからファイル名を抽出できますか?
この場合、grepが機能するには日付を知る必要があるため、lsは使用できません。
PS。コマンドを変数に保存することはお勧めできませんが、今はこれが必要で、後で変更できます。
答え1
これにより、指定された日付の間に変更されたファイルのすべてのパスが印刷されます。
find . -type f -newermt '2018-01-17' ! -newermt '2018-01-18'
ファイル名にスペース、タブ、改行、およびワイルドカードが含まれていない場合(まだ変更していない場合$IFS
)、スクリプトで使用すると機能します。
FILES=$(find /your/path -type f -newermt '2018-01-17' ! -newermt '2018-01-18')
for file in $FILES; do
echo "${file}"
done
ファイル名の代わりにパスを印刷します。
これらのファイルで実行したい操作に応じてfind -exec command
。
答え2
ls
シェルスクリプトでは、いかなる形式のコマンド出力も使用しないことがほとんど一般的に推奨されます。ls -1
代わりに(数字、「1」)を使用しても、ls -l
スペースなどのファイル名を処理する必要があります。
代わりに、セキュリティ印刷オプションと特定のファイルが生成されるタイミングを制限するオプションを指定してfind
このコマンドを使用してください。-print0
-ctime
答え3
この作業を安全に行うには、解析を行わず、可能であれば使用を避けるls
必要があります。eval
この提案では、ファイル名のスペースと奇妙な文字からコードを保護します。
date="Jan 10 2017"
find -type f -newermt "$date" \! -newermt "$date + 1 day" -printf '%P\0' |
while IFS= read -r -d $'\000' f;
do
echo ">> $f <<"
done
ファイル名のみをキャプチャしたい場合は、ループは必要なく、後続することなくwhile read
使用できます。find ... -printf "%P"
\0