ls -l 結果からファイル名を抽出する Bash スクリプト

ls -l 結果からファイル名を抽出する Bash スクリプト

特定の日付に生成されたファイルを見つけるように設計された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

関連情報