ディレクトリのリストを見つけて、そのディレクトリから特定のファイルを検索し、最新のファイルを選択したいと思います。
これが私が試したことです:
find /Temp -type d -name Ast 2>/dev/null | while read Dir; do find $Dir -type f -name Pagination.json 2>/dev/null -exec ls -lt {} +; done
これにより、予想されるファイルが表示されますが、昇順にソートされます。
このコマンドの結果は次のとおりです。
-rw-r--r-- 1 root root 46667 Sep 12 18:10 /Temp/ProjectOne/Site/Ast/BaseComponents/Pagination.json
-rw-r--r-- 1 root root 46667 Sep 13 09:31 /Temp/ProjectTwo/Site/Ast/BaseComponents/Pagination.json
この場合、2番目の項目が必要です。どうすればいいですか?
ベストアンサー1
私がこの問題を解決したのは、シェル自体のファイルルックアップ機能を使用してすべての候補を見つけ、最新のエントリを維持することでした。
#!/bin/bash
# enable ** as recursive glob, don't fail when null matches are found, and
# also look into things starting with .
shopt -s globstar nullglob dotglob
newestmod=0
for candidate in **/Ast/**/Pagination.json ; do
# check file type:
[[ -f ${candidate} ]] || continue
[[ -L ${candidate} ]] && continue
# Get modification time in seconds since epoch without fractional
# part. Assumes GNU stat or compatible.
thisdate=$(stat -c '%Y' -- "${candidate}")
# if older than the newest found, skip
[[ ${thisdate} -lt ${newestmod} ]] && continue
newestmod=${thisdate}
newestfile="${candidate}"
done
if (( newestmod )); then
printf 'Newest file: "%s"\n' "${newestfile}"
fi
またはそのようなもの。
では、zsh
すべてがあまり複雑ではなく、タイムスタンプの1秒未満の精度がサポートされています。
#!/usr/bin/zsh
#get the list of regular (`.`) files, `o`rdered by `m`odification date
allcandidates=(**/Ast/**/Pagination.json(ND.om))
if (( $#allcondidates )) print -r Newest file: $allcandidates[1]
それ以外の場合:
print -r Newest file: **/Ast/**/Pagination.json(D.om[1])
**/
zsh と bash5.0+ では、ディレクトリツリーを再帰的に巡回してもシンボリックリンクをたどりませんが、このセクションAst/
ではシンボリックリンクを巡回します。これが問題の場合は、次のzsh
方法で解決できます。
set -o extendedglob
print -r Newest file: ./**/Pagination.json~^*/Ast/*(D.om[1])
where は./**/Pagination.json
シンボリックリンクを経由せずにすべてのファイルを検索しますが、ここに含まれていないパターン~pattern
と一致するパスを削除します。^
/Ast/