GNU/Linux >> Znalost Linux >  >> Linux

Otestovat, zda existují soubory odpovídající vzoru, aby bylo možné spustit skript?

Snažím se napsat if příkaz k testování, zda existují nějaké soubory odpovídající určitému vzoru. Pokud je v adresáři textový soubor, měl by spustit daný skript.

Můj kód aktuálně:

if [ -f /*.txt ]; then ./script fi

Uveďte prosím nějaké nápady; Skript chci spustit pouze v případě, že existuje .txt v adresáři.

Přijatá odpověď:

[ -f /*.txt ]

vrátí true, pouze pokud existuje jeden (a pouze jeden) neskrytý soubor v / jehož jméno končí na .txt a pokud je tento soubor běžným souborem nebo symbolickým odkazem na běžný soubor.

Je to proto, že zástupné znaky jsou před předáním příkazu rozbaleny shellem (zde [ ).

Pokud tedy existuje /a.txt a /b.txt , [ bude předáno 5 argumentů:[ , -f , /a.txt , /b.txt a ] . [ by si pak stěžoval, že -f je uvedeno příliš mnoho argumentů.

Pokud chcete zkontrolovat, že *.txt vzor se rozšíří na alespoň jeden neskrytý soubor (běžný nebo ne) v bash shell:

shopt -s nullglob
set -- *.txt
if [ "$#" -gt 0 ]; then
  ./script "[email protected]" # call script with that list of files.
fi
# Or with bash arrays so you can keep the arguments:
files=( *.txt )
# apply C-style boolean on member count
(( ${#files[@]} )) && ./script "${files[@]}"

shopt -s nullglob je bash konkrétní (shopt je nullglob ve skutečnosti pochází z zsh ), ale shelly jako ksh93 , zsh , yash , tcsh mít ekvivalentní prohlášení.

Pomocí zsh , test na existují soubory odpovídající vzoru lze zapsat pomocí anonymní funkce a N (pro nullglob ) a Y1 (pro zastavení po prvním nalezení) kvalifikátor glob:

if ()(($#)) *.txt(NY1); then
  do-something
fi

Všimněte si, že tito najdou tyto soubory čtením obsahu adresáře, vůbec se nepokouší o přístup k těmto souborům, což je efektivnější než řešení, která volají příkazy jako ls nebo stat na tomto seznamu souborů vypočítaných shellem.

Standardní sh ekvivalent by byl:

set -- [*].txt *.txt
case "$1$2" in
  ('[*].txt*.txt') ;;
  (*) shift; script "[email protected]"
esac

Problém je v tom, že u shellů Bourne nebo POSIX, pokud vzor neodpovídá, roztáhne se sám na sebe. Pokud tedy *.txt se rozšíří na *.txt , nevíte, zda je to tím, že neexistuje žádný .txt soubor v adresáři nebo protože existuje jeden soubor s názvem *.txt . Pomocí [*].txt *.txt umožňuje rozlišovat mezi těmito dvěma.

Nyní, pokud chcete zkontrolovat, že *.txt odpovídá alespoň jednomu běžnému soubor nebo symbolický odkaz na běžný soubor (jako váš [ -f *.txt ] navrhuje, že chcete udělat), nebo že všechny soubory, které odpovídají *.txt jsou pravidelné soubory (po rozlišení symbolických odkazů), to je další věc.

Související:Jak vygenerovat skript pro vytvoření tabulky bez primárního a cizího klíče v Oracle?

Pomocí zsh :

if ()(($#)) *.txt(NY1-.); then
  echo "there is at least one regular .txt file"
fi
if ()(($#)) *.txt(NY1^-.); then
  echo "there is at least one non-regular .txt files"
fi

(odstraňte - pokud chcete provést test před rozlišením symbolických odkazů, považujte symbolické odkazy za nestandardní soubory, ať už odkazují na běžné soubory nebo ne).


Linux
  1. Je možné zjistit, jaký program nebo skript vytvořil daný soubor?

  2. Najít duplicitní soubory?

  3. Cat soubory s adresářem?

  1. Nahradit řádky odpovídající vzoru řádky z jiného souboru v pořadí?

  2. Skript pro zjištění, zda jsou soubory obrázky?

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

  1. Existuje program/script pro úpravu souborů .conf?

  2. Zkopírujte všechny soubory odpovídající vzoru z adresáře a podadresářů do jednoho adresáře

  3. Jak předat více argumentů ke spuštění pomocí skriptu .sh