it-swarm-eu.dev

Jak mohu uvést všechny soubory v adresáři kromě těch, které mají zadané přípony?

Předpokládejme, že mám složku obsahující . Txt, . Pdf a další soubory. Chtěl bych uvést seznam „dalších“ souborů (tj. Soubory, které nemají přípony . Txt nebo . Pdf). Máte nějaké rady, jak to udělat?

Vím, jak vypsat soubory, které nemají danou příponu. Pokud například chci uvést všechny soubory kromě souborů . Txt, pak buď

find -not -iname "*.txt"

nebo

ls | grep -v '\.txt$' | column

zdá se, že funguje. Jak ale mohu uvést vše kromě . Txt souborů nebo . Pdf souborů? Zdá se, že musím použít nějaký logický "nebo" v find nebo grep.

31
Andrew

Za předpokladu, že jeden má GNU ls, je to pravděpodobně nejjednodušší způsob:

ls -I "*.txt" -I "*.pdf"

Pokud chcete iterovat ve všech podadresářích:

ls -I "*.txt" -I "*.pdf" -R
31
Dejian

Najít podpory -o

find . ! '(' -name '*.txt' -o -name '*.pdf' ')'

Aby byla priorita správná, potřebujete závorky. Najít dělá spoustu věcí; Navrhuji přečíst si jeho manpage.

Můžete také provést nebo v grep (ale ve skutečnosti byste neměli byste analyzovat výstup ls )

ls | grep -Ev '\.(txt|pdf)$' | column
30
derobert

S rozšířením globalizace bash (zapněte pomocí shopt -s extglob) By glob !(*.txt|*.pdf) měl fungovat. Tento glob můžete předat přímo každému příkazu, který vezme argumenty souboru, včetně, ale bez omezení na ls.

12
jw013

V zsh s extendedglob:

print -rl -- *~*.(txt|pdf)

nebo

print -rl -- ^*.(txt|pdf)

Nebo s kshglob (ano, to je ksh globbing, nikoli „bash Extended globbing“):

print -rl -- !(*.txt|*.pdf)

Nezapomeňte však, že tyto soubory také vylučují tečky.

ksh93 má funkci FIGNORE (mis):

FIGNORE='@(.|..|*.txt|*.pdf)'
printf '%s\n' *
6
Thor
find /path/to/directory '!' -name '*.pdf' '!' -name '*.txt'

Toto je ekvivalentní příkazu s operátorem OR, protože De Morganovy zákony .

4
Francesco Turco

Jak navrhuje derobert, nejlepší je použít find. Avšak can ve skutečnosti použijete výsledek v potrubí s dalšími příkazy.

GNU (a některé BSD) find podporují -print0 predikát, který říká, že má tisknout název souboru zakončený znakem NUL , který není v názvu souboru povolen a zaručuje, že nebude kolize. Ostatní příkazy mohou být instruovány k použití NUL jako oddělovače vstupu.

Nejdůležitější z nich je GNU xargs, který spustí zadaný příkaz a předá mu seznam souborů jako argumenty příkazového řádku. Chcete spustit xargs -r0 ve spojení s nálezci -print0 Například:

find . -type f ! \( -name \*.pdf -o -name \*.txt \) -print0 | xargs -r0 ls -ld

Tím se bezpečně vytiskne dlouhý adresářový výpis všech souborů pdf a txt, včetně souborů s mezerami nebo netisknutelnými znaky v názvu.

Můžete ji také použít s GNU tar takto:

tar -zcf myarchive.tar.gz --null --files-from <(
  find . -type f ! -name \*.tar.gz -print0)

Tím se vytvoří soubor tar.gz všech souborů, jejichž jména nekončí .tar.gz

rsync také přijímá nulově oddělené soubory s -0 parametr, stejně jako několik dalších. Ale xargs je lepidlo, které obvykle používáte pro tento typ účelu. Buď to nebo find 's -exec Vlastnosti.

3
tylerl

Pokud nemáte podadresář

ls !(*.pdf|*.txt)

by také mělo fungovat!

Ale

ls -I "*.pdf" -I "*.txt"

je běžná cesta.

0
abu_bua

Jako doplněk, pokud používáte prostředí kompatibilní s bash, můžete použít proměnnou GLOBIGNORE k vyloučení resuts z porovnávání vzorů. Od muže:

   GLOBIGNORE
          A colon-separated list of patterns defining the set of filenames
          to be ignored by pathname expansion.  If a filename matched by a
          pathname  expansion  pattern also matches one of the patterns in
          GLOBIGNORE, it is removed from the list of matches.

Ve vašem konkrétním případě:

sh$ (GLOBIGNORE='*.pdf:*.txt'; ls -d *)

Vezměte prosím na vědomí, že tento příkaz spouštím jako subshell (pomocí závorek), abych nezměnil proměnnou prostředí GLOBIGNORE mého interaktivního Shell.

0
Sylvain Leroux