GNU/Linux >> Znalost Linux >  >> Linux

Funkce Bash pro nalezení nejnovějšího vzoru pro shodu souborů

Kombinace find a ls funguje dobře pro

  • názvy souborů bez nových řádků
  • nepříliš velké množství souborů
  • nepříliš dlouhé názvy souborů

Řešení:

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

Pojďme to rozebrat:

S find můžeme spárovat všechny zajímavé soubory takto:

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

poté pomocí -print0 můžeme všechny názvy souborů bezpečně předat do ls takhle:

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

další find parametry vyhledávání a vzory lze přidat zde

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

ls -t seřadí soubory podle času úpravy (nejnovější jako první) a vytiskne je jeden na řádku. Můžete použít -c seřadit podle času vytvoření. Poznámka :toto přeruší názvy souborů obsahujících nové řádky.

Nakonec head -1 dostane první soubor v seřazeném seznamu.

Poznámka: xargs použijte systémové limity velikosti seznamu argumentů. Pokud tato velikost překročí, xargs zavolá ls vícekrát. Tím se rozbije řazení a pravděpodobně i konečný výstup. Spustit

xargs  --show-limits

zkontrolovat limity vašeho systému.

Poznámka 2: použijte find . -maxdepth 1 -name "my-pattern" -print0 pokud nechcete prohledávat soubory v podsložkách.

Poznámka 3: Jak zdůraznil @starfry - -r argument pro xargs brání volání ls -1 -t , pokud žádné soubory neodpovídají find . Děkujeme za návrh.


ls příkaz má parametr -t seřadit podle času. Pak můžete získat první (nejnovější) s head -1 .

ls -t b2* | head -1

Ale pozor:Proč byste neměli analyzovat výstup ls

Můj osobní názor:parsování ls je nebezpečné pouze tehdy, když názvy souborů mohou obsahovat zábavné znaky, jako jsou mezery nebo nové řádky. Pokud můžete zaručit, že názvy souborů nebudou obsahovat vtipné znaky, pak analyzujte ls je docela bezpečný.

Pokud vyvíjíte skript, který má být spouštěn mnoha lidmi na mnoha systémech v mnoha různých situacích, pak velmi doporučuji neanalyzovat ls .

Zde je návod, jak to udělat „správně“:Jak najdu nejnovější (nejnovější, nejstarší, nejstarší) soubor v adresáři?

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

Toto je možná implementace požadované funkce 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
}

Používá pouze vestavěné moduly Bash a měl by zpracovávat soubory, jejichž názvy obsahují nové řádky nebo jiné neobvyklé znaky.


Linux
  1. najít a zkopírovat soubor pomocí Bash

  2. Jak změnit oprávnění pro určitý vzor souboru/příponu?

  3. Rekurzivně měnit přípony souborů v Bash

  1. Porovnávání vzorů skriptů Bash

  2. Najít soubor odpovídající určitému vzoru a dát tomuto názvu souboru jako hodnotu proměnné ve skriptu shellu?

  3. bash - shoda proměnné bez ohledu na velikost písmen

  1. The Bash ‘?

  2. Jak vyhledávat v konkrétních souborech odpovídajících vzoru?

  3. Jak použít příkaz find k odstranění souborů odpovídajících vzoru?