menemukan nama file TIDAK berakhir dengan ekstensi spesifik di Unix?

207

Apakah ada cara sederhana untuk secara rekursif menemukan semua file dalam hierarki direktori, yang tidak berakhir dengan daftar ekstensi? Misalnya semua file yang bukan * .dll atau * .exe

UNIX / GNU menemukan, sekuat itu, tampaknya tidak memiliki excludemode (atau saya kehilangan itu), dan saya selalu merasa sulit untuk menggunakan ekspresi reguler untuk menemukan hal-hal yang tidak cocok dengan ekspresi tertentu .

Saya berada di lingkungan Windows (menggunakan port GnuWin32 pada sebagian besar alat GNU), jadi saya sama-sama terbuka untuk solusi Windows saja.

Cristian Diaconescu
sumber

Jawaban:

343

Atau tanpa (dan kebutuhan untuk menghindarinya:

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

dan juga mengecualikan daftar direktori

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

atau dalam logika positif ;-)

find . -not -name "*.exe" -not -name "*.dll" -type f
Kuat
sumber
6
-notdapat diganti dengan '!'(Penawaran disarankan). Di sisi lain, -namecase sensitif sedangkan -inamecase sensitif.
Ivan Chau
45
find . ! \( -name "*.exe" -o -name "*.dll" \)
Chen Levy
sumber
2
Pada Solaris -notadalah pilihan yang buruk, yang ini !bekerja dengan baik :)
DmitrySandalov
8
$ find . -name \*.exe -o -name \*.dll -o -print

Dua opsi-nama pertama tidak memiliki opsi -print, sehingga dilewati. Semuanya dicetak.

Jeff Ferland
sumber
4

Anda bisa melakukan sesuatu menggunakan perintah grep:

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

The -vbendera pada grepkhususnya berarti "menemukan hal-hal yang tidak sesuai dengan ungkapan ini."

VoteyDisciple
sumber
6
grep -v '\. (dll | exe) $' akan mencegah pencocokan terhadap file atau direktori bernama "dexe" misalnya
drAlberT
Ini hanya bekerja dengan regexp tambahan. Saya harus menambahkan -E (atau menggunakan egrep) untuk membuat ini berfungsi.
Joctee
2

satu lagi :-)

$ ls -ltr
total 10
-rw-r - r-- 1 scripter linuxdumb 47 Des 23 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
$ temukan. -type f! -nama "* 1"! -nama "* 2" -cetak
./test3
./test4
./file3
./file4
./file5
$

Unix temukan referensi perintah

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

Linux / OS X:

Mulai dari direktori saat ini, secara rekursif menemukan semua file yang berakhiran .dll atau .exe

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

Mulai dari direktori saat ini, secara rekursif menemukan semua file yang TIDAK diakhiri dengan .dll atau .exe

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

Catatan:

(1) Opsi P dalam grep menunjukkan bahwa kita menggunakan gaya Perl untuk menulis ekspresi reguler kita untuk digunakan bersama dengan perintah grep . Untuk tujuan mengeksekusi perintah grep bersama dengan ekspresi reguler, saya menemukan bahwa gaya Perl adalah gaya yang paling kuat di sekitar.

(2) Opsi v di grep menginstruksikan shell untuk mengecualikan file apa pun yang memenuhi ekspresi reguler

(3) $ karakter di akhir mengatakan ".dll $" adalah karakter kontrol pembatas yang memberitahu shell bahwa string nama file diakhiri dengan ".dll"

Vietnhi Phuvan
sumber
0

Solusi lain pada halaman ini tidak diinginkan jika Anda memiliki daftar ekstensi yang panjang - mempertahankan urutan panjang -not -name 'this' -not -name 'that' -not -name 'other'akan membosankan dan rentan kesalahan - atau jika pencarian terprogram dan daftar ekstensi dibuat saat runtime.

Untuk situasi tersebut, solusi yang lebih jelas memisahkan data (daftar ekstensi) dan kode (parameter untuk find) mungkin diinginkan. Diberikan struktur direktori & file yang terlihat seperti ini:

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

Anda dapat melakukan sesuatu seperti ini:

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

Yang mengakibatkan:

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

Anda dapat mengubah daftar ekstensi tanpa mengubah blok kode.

CATATAN tidak berfungsi dengan OSX asli find- gunakan gnu find saja.

Chris Johnson
sumber