ディレクトリリストで最新のファイルを検索するよう強制

ディレクトリリストで最新のファイルを検索するよう強制

ディレクトリのリストを見つけて、そのディレクトリから特定のファイルを検索し、最新のファイルを選択したいと思います。

これが私が試したことです:

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/

おすすめ記事