ファイルリストから最新の項目を見つけるスクリプト

ファイルリストから最新の項目を見つけるスクリプト

newer.shファイルのリストが与えられたら、最新のファイルを返すスクリプトを作成する必要があります。つまり、次のように入力します。

newer.sh /some/file other-file /and/so/on

リストの最新のファイル名を返します。

これまで私が考えることができるのは次のとおりです。

#!/bin/bash
echo "Newest file:"
ls -t | head -n 1

実際には、作成時間に基づいて生成された最新のファイルが返されますが、現在のディレクトリのファイルにのみ適用されます。

ベストアンサー1

GNUツールの使用:

#! /bin/bash -
export LC_ALL=C
eval "files=($(ls -dt --quoting-style=shell-always -- "${@?}"))"
((${#files[@]} > 0)) && printf '%s\n' "${files[0]}"

シンボリックリンクの場合、シンボリックリンク自体の最後の修正時間を考慮します。シンボリックリンクのターゲットにするには、-Lこのオプションをls

引数として指定されたファイルパスに改行文字を含めることができないという制限を追加するには、次のように書くことができます。

#! /bin/sh -
# only works for file paths that don't contain newline characters
[ "$#" -gt 0 ] && ls -td -- "$@" | head -n 1

GNUツールへの依存関係を削除します。

原則は同じです。使用される関数は、ls -t変更時間に基づいてファイルをソートし、そのリストの最初のファイルを取得します。ただし、ここでは1行に1つのファイルのリストが出力されるため、ファイルパスに改行文字が含まれていないことを保証できないと、安定して解析することはできません(そうでなければ、名前付きの2つのファイルをls区別できません)。最新のファイル)実際に提供された誤った結果。a<newline>baba<newline>bhead -n 1a

あなたのアプローチとは異なり、ここではスクリプトが受け取る引数のリストを"$@"渡しますls--引数がオプションlsではなくファイルオペランドとして扱われるようにaの後に)、オプションがリストされないように渡し-dますlsコンテンツこのファイルの種類目次。また、スクリプトがゼロ個の引数(== 0)を受け取っても、$#これは行われません。それ以外の場合は、ls -td --現在のディレクトリが一覧表示され、.出力が得られます。

GNUに加えて、GNUを使用してソートできる方法でファイルの修正時間を取得するためにlsGNUを使用することもできます。statsort

#! /bin/sh -
export TZ=UTC0 LC_ALL=C
stat --printf '%y@%n\0' -- "$@" | sort -rz | sed -z 's/^[^@]*@//;q' | tr '\0' '\n'

sed(には最新バージョンのGNUを使用してください-z。)またはGNUを使用してくださいawk

#! /bin/sh -
export TZ=UTC0 LC_ALL=C
stat --printf '%y@%n\0' -- "$@" | awk -v RS='\0' '
  NR == 1 || $0 > newest {newest = $0}
  END {if (NR) {sub(/[^@]*@/, "", newest); print newest}}'

おすすめ記事