GNU/Linux >> Linux の 問題 >  >> Linux

パターンに一致する最新のファイルを見つけるための Bash 関数

find の組み合わせ と ls に適しています

  • 改行なしのファイル名
  • それほど多くないファイル
  • あまり長くないファイル名

解決策:

find . -name "my-pattern" -print0 |
    xargs -r -0 ls -1 -t |
    head -1

分解してみましょう:

find で 次のように、すべての興味深いファイルを一致させることができます:

find . -name "my-pattern" ...

次に -print0 を使用 すべてのファイル名を ls に安全に渡すことができます このように:

find . -name "my-pattern" -print0 | xargs -r -0 ls -1 -t

追加の find ここに検索パラメータとパターンを追加できます

find . -name "my-pattern" ... -print0 | xargs -r -0 ls -1 -t

ls -t ファイルを変更時間 (最新のものから順に) でソートし、1 行に 1 つずつ出力します。 -c を使用できます 作成時間順に並べ替えます。 注意 :これは、改行を含むファイル名で壊れます。

最後に head -1 ソートされたリストの最初のファイルを取得します。

注: xargs 引数リストのサイズにシステム制限を使用します。このサイズを超える場合、xargs ls を呼び出します 複数回。これにより、ソートが中断され、おそらく最終出力も中断されます。実行

xargs  --show-limits

システムの制限を確認してください。

注 2: find . -maxdepth 1 -name "my-pattern" -print0 を使用 サブフォルダーからファイルを検索したくない場合。

注 3: @starfry が指摘したように - -r xargs の引数 ls -1 -t の呼び出しを妨げています find に一致するファイルがなかった場合 .提案ありがとうございます。


ls コマンドにはパラメータ -t があります 時間順に並べ替えます。 head -1 で最初 (最新) を取得できます .

ls -t b2* | head -1

ただし、注意してください:ls の出力を解析してはならない理由

私の個人的な意見:ls の解析 ファイル名にスペースや改行などの変な文字が含まれている場合にのみ危険です。ファイル名に変な文字が含まれていないことを保証できる場合は、 ls を解析します

多くの人が多くのシステムでさまざまな状況で実行することを意図したスクリプトを開発している場合は、ls を解析しないことを強くお勧めします。 .

これを「正しく」実行する方法は次のとおりです:ディレクトリ内の最新 (最新、最古、最古) のファイルを見つけるにはどうすればよいですか?

unset -v latest
for file in "$dir"/*; do
  [[ $file -nt $latest ]] && latest=$file
done

これは、必要な Bash 関数の可能な実装です:

# Print the newest file, if any, matching the given pattern
# Example usage:
#   newest_matching_file 'b2*'
# WARNING: Files whose names begin with a dot will not be checked
function newest_matching_file
{
    # Use ${1-} instead of $1 in case 'nounset' is set
    local -r glob_pattern=${1-}

    if (( $# != 1 )) ; then
        echo 'usage: newest_matching_file GLOB_PATTERN' >&2
        return 1
    fi

    # To avoid printing garbage if no files match the pattern, set
    # 'nullglob' if necessary
    local -i need_to_unset_nullglob=0
    if [[ ":$BASHOPTS:" != *:nullglob:* ]] ; then
        shopt -s nullglob
        need_to_unset_nullglob=1
    fi

    newest_file=
    for file in $glob_pattern ; do
        [[ -z $newest_file || $file -nt $newest_file ]] \
            && newest_file=$file
    done

    # To avoid unexpected behaviour elsewhere, unset nullglob if it was
    # set by this function
    (( need_to_unset_nullglob )) && shopt -u nullglob

    # Use printf instead of echo in case the file name begins with '-'
    [[ -n $newest_file ]] && printf '%s\n' "$newest_file"

    return 0
}

Bash ビルトインのみを使用し、名前に改行やその他の特殊な文字が含まれるファイルを処理する必要があります。


Linux
  1. Bash:Find Into Selectの空白に安全な手続き上の使用?

  2. Firefoxのログファイルを見つけますか?

  3. アクセス許可を特定のファイル パターン/拡張子に変更するには?

  1. Bash でファイル拡張子を再帰的に変更する

  2. 特定のパターンに一致するファイルを見つけ、そのファイル名をシェル スクリプトの変数に値として指定しますか?

  3. bash - 大文字と小文字を区別しない変数のマッチング

  1. バッシュ‘?

  2. パターンに一致する特定のファイルを検索する方法は?

  3. Bash を使用してファイルを検索してコピーする