Dateinamen finden, die unter Unix NICHT mit bestimmten Erweiterungen enden?

207

Gibt es eine einfache Möglichkeit, alle Dateien in einer Verzeichnishierarchie rekursiv zu finden, die nicht in einer Liste von Erweiterungen enden? ZB alle Dateien, die nicht * .dll oder * .exe sind

UNIX / GNU find, so mächtig es auch ist, scheint keinen excludeModus zu haben (oder ich vermisse ihn), und ich fand es immer schwierig, reguläre Ausdrücke zu verwenden, um Dinge zu finden, die nicht zu einem bestimmten Ausdruck passen .

Ich bin in einer Windows-Umgebung (mit dem GnuWin32- Port der meisten GNU-Tools), daher bin ich auch offen für reine Windows-Lösungen.

Cristian Diaconescu
quelle

Antworten:

343

Oder ohne (und die Notwendigkeit, ihm zu entkommen:

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

und auch die Auflistung von Verzeichnissen auszuschließen

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

oder in positiver Logik ;-)

find . -not -name "*.exe" -not -name "*.dll" -type f
Winterhart
quelle
6
-notkann ersetzt werden durch '!'(Zitat wird empfohlen). Auf der anderen Seite -namewird zwischen Groß- und Kleinschreibung unterschieden, während zwischen -inameGroß- und Kleinschreibung unterschieden wird.
Ivan Chau
45
find . ! \( -name "*.exe" -o -name "*.dll" \)
Chen Levy
quelle
2
Unter Solaris -notist eine schlechte Option, diese !funktioniert gut :)
DmitrySandalov
8
$ find . -name \*.exe -o -name \*.dll -o -print

Die ersten beiden -name-Optionen haben keine -print-Option, daher wurden sie übersprungen. Alles andere wird gedruckt.

Jeff Ferland
quelle
4

Mit dem Befehl grep können Sie Folgendes tun:

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

Das -vFlag auf grepbedeutet speziell "Finde Dinge, die nicht zu diesem Ausdruck passen".

VoteyDisciple
quelle
6
grep -v '\. (dll | exe) $' würde beispielsweise den Abgleich mit einer Datei oder einem Verzeichnis mit dem Namen "dexe" verhindern
drAlberT
Dies funktioniert nur mit erweitertem regulären Ausdruck. Ich musste -E hinzufügen (oder egrep verwenden), damit dies funktioniert.
Joctee
2

einer noch :-)

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

Unix-Befehlsreferenz suchen

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

Linux / OS X:

Suchen Sie ausgehend vom aktuellen Verzeichnis rekursiv alle Dateien, die auf .dll oder .exe enden

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

Suchen Sie ausgehend vom aktuellen Verzeichnis rekursiv alle Dateien, die NICHT mit .dll oder .exe enden

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

Anmerkungen:

(1) Die Option P in grep gibt an, dass wir den Perl-Stil verwenden, um unsere regulären Ausdrücke zu schreiben, die in Verbindung mit dem Befehl grep verwendet werden sollen . Um den Befehl grep in Verbindung mit regulären Ausdrücken auszuführen , finde ich, dass der Perl-Stil der mächtigste Stil ist, den es gibt.

(2) Die Option v in grep weist die Shell an, alle Dateien auszuschließen, die den regulären Ausdruck erfüllen

(3) Das $ -Zeichen am Ende von ".dll $" ist ein Trennzeichen-Steuerzeichen, das der Shell mitteilt, dass die Dateinamenzeichenfolge mit ".dll" endet.

Vietnhi Phuvan
quelle
0

Andere Lösungen auf dieser Seite sind nicht wünschenswert, wenn Sie eine lange Liste von Erweiterungen haben - eine lange Folge von Erweiterungen -not -name 'this' -not -name 'that' -not -name 'other'wäre mühsam und fehleranfällig - oder wenn die Suche programmgesteuert ist und die Liste der Erweiterungen zur Laufzeit erstellt wird.

In solchen Situationen kann eine Lösung findwünschenswert sein, die Daten (die Liste der Erweiterungen) und Code (die Parameter zu ) klarer voneinander trennt . Bei einer Verzeichnis- und Dateistruktur, die folgendermaßen aussieht:

.
└── 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

Sie können so etwas tun:

## 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\)"

Was in ... endet:

./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

Sie können die Erweiterungsliste ändern, ohne den Codeblock zu ändern.

HINWEIS funktioniert nicht mit nativem OSX find- verwenden Sie stattdessen gnu find.

Chris Johnson
quelle