trovare i nomi di file NON terminano con estensioni specifiche su Unix?


207

Esiste un modo semplice per trovare ricorsivamente tutti i file in una gerarchia di directory, che non finiscono in un elenco di estensioni? Ad esempio tutti i file che non sono * .dll o * .exe

UNIX / GNU trova, per quanto potente, non sembra avere una excludemodalità (o mi manca), e ho sempre trovato difficile usare espressioni regolari per trovare cose che non corrispondono a un'espressione particolare .

Sono in un ambiente Windows (usando la porta GnuWin32 della maggior parte degli strumenti GNU), quindi sono ugualmente aperto per soluzioni solo per Windows.

Risposte:


343

O senza (e la necessità di evitarlo:

find . -not -name "*.exe" -not -name "*.dll"

e per escludere anche l'elenco delle directory

find . -not -name "*.exe" -not -name "*.dll" -not -type d

o in logica positiva ;-)

find . -not -name "*.exe" -not -name "*.dll" -type f

6
-notpuò essere sostituito da '!'(preventivo raccomandato). D'altra parte, -namedistingue tra maiuscole e minuscole mentre -inamedistingue tra maiuscole e minuscole.
Ivan Chau,


8
$ find . -name \*.exe -o -name \*.dll -o -print

Le prime opzioni a due nomi non hanno alcuna opzione di stampa, quindi hanno saltato. Tutto il resto è stampato.


4

Puoi fare qualcosa usando il comando grep:

find . | grep -v '(dll|exe)$'

La -vbandiera su grepsignifica specificamente "trova cose che non corrispondono a questa espressione".


6
grep -v '\. (dll | exe) $' impedirebbe di nuovo la corrispondenza di un file o di una directory denominata "dexe", ad esempio
drAlberT

Funziona solo con regexp esteso. Ho dovuto aggiungere -E (o usare egrep) per farlo funzionare.
Giovedi

2

un altro :-)

$ ls -ltr
totale 10
-rw-r - r-- 1 scripter linuxdumb 47 dic 23 14:46 test1
-rw-r - r-- 1 scripter linuxdumb 0 gen 4 23:40 test4
-rw-r - r-- 1 scripter linuxdumb 0 4 gen 23:40 test3
-rw-r - r-- 1 scripter linuxdumb 0 4 gen 23:40 test2
-rw-r - r-- 1 scripter linuxdumb 0 4 gen 23:41 file5
-rw-r - r-- 1 scripter linuxdumb 0 4 gen 23:41 file4
-rw-r - r-- 1 scripter linuxdumb 0 4 gen 23:41 file3
-rw-r - r-- 1 scripter linuxdumb 0 4 gen 23:41 file2
-rw-r - r-- 1 scripter linuxdumb 0 4 gen 23:41 file1
$ find. tipo f! -name "* 1"! -name "* 2" -print
./test3
./test4
./file3
./file4
./file5
$

Unix trova il riferimento al comando


1
find  /data1/batch/source/export   -type f -not  -name "*.dll" -not -name "*.exe"

1

Linux / OS X:

A partire dalla directory corrente, trova ricorsivamente tutti i file che terminano in .dll o .exe

find . -type f | grep -P "\.dll$|\.exe$"

A partire dalla directory corrente, trova ricorsivamente tutti i file che NON finiscono in .dll o .exe

find . -type f | grep -vP "\.dll$|\.exe$"

Appunti:

(1) L'opzione P in grep indica che stiamo usando lo stile Perl per scrivere le nostre espressioni regolari da usare insieme al comando grep . Allo scopo di eseguire il comando grep insieme alle espressioni regolari, trovo che lo stile Perl sia lo stile più potente in circolazione.

(2) L'opzione v in grep indica alla shell di escludere qualsiasi file che soddisfi l'espressione regolare

(3) Il carattere $ alla fine di dire ".dll $" è un carattere di controllo delimitatore che dice alla shell che la stringa del nome file termina con ".dll"


0

Altre soluzioni in questa pagina non sono desiderabili se si dispone di un lungo elenco di estensioni - il mantenimento di una lunga sequenza -not -name 'this' -not -name 'that' -not -name 'other'sarebbe noioso e soggetto a errori - o se la ricerca è programmatica e l'elenco di estensioni viene creato in fase di esecuzione.

Per tali situazioni, findpuò essere desiderabile una soluzione che separa più chiaramente i dati (l'elenco delle estensioni) e il codice (i parametri da ). Data una struttura di directory e file che assomiglia a questa:

.
└── a
    ├── 1.txt
    ├── 15.xml
    ├── 8.dll
    ├── b
    │   ├── 16.xml
    │   ├── 2.txt
    │   ├── 9.dll
    │   └── c
    │       ├── 10.dll
    │       ├── 17.xml
    │       └── 3.txt
    ├── d
    │   ├── 11.dll
    │   ├── 18.xml
    │   ├── 4.txt
    │   └── e
    │       ├── 12.dll
    │       ├── 19.xml
    │       └── 5.txt
    └── f
        ├── 13.dll
        ├── 20.xml
        ├── 6.txt
        └── g
            ├── 14.dll
            ├── 21.xml
            └── 7.txt

Puoi fare qualcosa del genere:

## data section, list undesired extensions here
declare -a _BADEXT=(xml dll)

## code section, this never changes
BADEXT="$( IFS="|" ; echo "${_BADEXT[*]}" | sed 's/|/\\|/g' )"
find . -type f ! -regex ".*\.\($BADEXT\)"

Che si traduce in:

./a/1.txt
./a/b/2.txt
./a/b/c/3.txt
./a/d/4.txt
./a/d/e/5.txt
./a/f/6.txt
./a/f/g/7.txt

È possibile modificare l'elenco delle estensioni senza modificare il blocco di codice.

NOTA non funziona con OSX nativo find- usa invece gnu find.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.