Bagaimana cara menggunakan regex dengan perintah find?

298

Saya memiliki beberapa gambar bernama dengan string uuid1 yang dihasilkan. Misalnya 81397018-b84a-11e0-9d2a-001b77dc0bed.jpg. Saya ingin mencari tahu semua gambar ini menggunakan perintah "find":

find . -regex "[a-f0-9\-]\{36\}\.jpg".

Tapi itu tidak berhasil. Ada yang salah dengan regex? Bisakah seseorang membantu saya dengan ini?

thoslin
sumber
7
mungkin mengubah regextype. Standarnya adalah Emacs Regular Expressions , apa pun artinya.
pavium

Jawaban:

349
find . -regextype sed -regex ".*/[a-f0-9\-]\{36\}\.jpg"

Perhatikan bahwa Anda perlu menentukan .*/di awal karena findcocok dengan seluruh jalur.

Contoh:

susam@nifty:~/so$ find . -name "*.jpg"
./foo-111.jpg
./test/81397018-b84a-11e0-9d2a-001b77dc0bed.jpg
./81397018-b84a-11e0-9d2a-001b77dc0bed.jpg
susam@nifty:~/so$ 
susam@nifty:~/so$ find . -regextype sed -regex ".*/[a-f0-9\-]\{36\}\.jpg"
./test/81397018-b84a-11e0-9d2a-001b77dc0bed.jpg
./81397018-b84a-11e0-9d2a-001b77dc0bed.jpg

Versi pencarian saya:

$ find --version
find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Built using GNU gnulib version e5573b1bad88bfabcda181b9e0125fb0c52b7d3b
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS() CBO(level=0) 
susam@nifty:~/so$ 
susam@nifty:~/so$ find . -regextype foo -regex ".*/[a-f0-9\-]\{36\}\.jpg"
find: Unknown regular expression type `foo'; valid types are `findutils-default', `awk', `egrep', `ed', `emacs', `gnu-awk', `grep', `posix-awk', `posix-basic', `posix-egrep', `posix-extended', `posix-minimal-basic', `sed'.
Susam Pal
sumber
4
@ Tom, itulah cara regex dalam menemukan karya. Menurut halaman manual, regex cocok dengan seluruh path file, termasuk direktori, yang berarti ada implisit di "^ ... $"sekitar regex Anda. Itu harus cocok dengan garis hasil SELURUH.
Manny D
2
Saya tidak berpikir Anda perlu /dalam .*/karena .*cocok dengan nol atau lebih dari (hampir) karakter apa pun.
Jeff
2
Bagi mereka (seperti saya) yang tidak membaca regex dengan benar pertama kali: Catat backslash yang mendahului karakter regex khusus, misalnya:\{36\}
Lucas Wilson-Richter
11
Saya mengalami kesulitan menemukan daftar lengkap jenis regex (halaman manual tidak up to date):valid types are 'findutils-default', 'awk', ' egrep', 'ed', 'emacs', 'gnu-awk', 'grep', 'posix-awk', 'posix-basic', 'posix-egrep', 'posix -extended', 'posix-minimal-basic', 'sed'.
Noah Sussman
4
Pastikan untuk menempatkan -regextypebendera sebelum para -regexbendera, jika tidak maka tidak berlaku!
Christopher Orr
84

The -regexekspresi menemukan sesuai dengan seluruh nama , termasuk path relatif dari direktori saat ini. Untuk find .ini selalu dimulai dengan ./, lalu direktori apa pun.

Juga, ini adalah emacsekspresi reguler, yang memiliki aturan pelarian lain selain ekspresi reguler egrep biasa.

Jika ini semua langsung di direktori saat ini, maka

find . -regex '\./[a-f0-9\-]\{36\}\.jpg'

harus bekerja. (Saya tidak begitu yakin - Saya tidak bisa mendapatkan pengulangan yang dihitung untuk bekerja di sini.) Anda dapat beralih ke ekspresi egrep dengan -regextype posix-egrep:

find . -regextype posix-egrep -regex '\./[a-f0-9\-]{36}\.jpg'

(Perhatikan bahwa semua yang dikatakan di sini adalah untuk menemukan GNU, saya tidak tahu apa-apa tentang BSD yang juga merupakan default pada Mac.)

Paŭlo Ebermann
sumber
1
Saya memiliki tanda kurung untuk beberapa string yang cocok di regex saya, jadi posix-egreptipe itu berfungsi untuk saya.
palswim
2
Sesuatu yang perlu diperhatikan, -regextypeadalah opsi untuk GNU finddan bukan BSD (setidaknya tidak seperti Mac BSD) find. Jika opsi ini tidak tersedia, pastikan untuk menginstal GNU find. Jika pada Mac itu mungkin dengan paket minuman findutils. Temukan kemudian tersedia melalui gfind.
DanCat
regextype posix-egrep melakukan tugas untuk saya. Saya pikir defaultnya adalah regextype emacs.
infoclogged
35

Menilai dari jawaban lain, sepertinya ini adalah kesalahan find.

Namun Anda dapat melakukannya dengan cara ini sebagai gantinya:

find . * | grep -P "[a-f0-9\-]{36}\.jpg"

Anda mungkin harus mengubah sedikit grep dan menggunakan opsi yang berbeda tergantung pada apa yang Anda inginkan tetapi berfungsi.

yarian
sumber
Bekerja dengan baik untuk saya dan memberikan tingkat kebebasan yang besar sehubungan dengan regex.
glaucon
3
Kelemahan dengan ini adalah bahwa Anda tidak dapat mengambil keuntungan dari find's -prunefungsi yang akan melewatkan direktori tertentu sama sekali. Paling sering ini tidak terlalu penting, tetapi perlu disebutkan.
Alexander Bird
-prune masih akan bekerja, kurasa. Akan lebih berbahaya untuk menggunakan -exec - ini akan berjalan pada semua file dan bukan hanya file yang memungkinkan grep untuk dilewati.
tpb261
13

pada Mac OS X (BSD find) : Sama seperti jawaban yang diterima, .*/awalan diperlukan untuk mencocokkan jalur lengkap:

$ find -E . -regex ".*/[a-f0-9\-]{36}.jpg"

man findmengatakan -Emenggunakan dukungan regex yang diperluas

Stan Kurdziel
sumber
Tampaknya -Etidak tersedia di Ubuntu (diuji pada WSL Ubuntu)
Warlike Chimpanzee
2
@Clever Little Monkey - Tidak, jawaban yang diterima harus bekerja di Ubuntu, variasi ini untuk Mac OS X secara khusus (atau mungkin varian BSD lainnya seperti FreeBSD)
Stan Kurdziel
8

Coba gunakan tanda kutip tunggal (') untuk menghindari shell melarikan diri dari string Anda. Ingatlah bahwa ekspresi harus sesuai dengan keseluruhan jalur, yaitu harus terlihat seperti:

 find . -regex '\./[a-f0-9-]*.jpg'

Terlepas dari itu, tampaknya temuan saya (GNU 4.4.2) hanya mengetahui ekspresi reguler dasar, terutama bukan sintaks {36}. Saya pikir Anda harus melakukannya tanpa itu.

thiton
sumber
8

Cara sederhana - Anda dapat menentukan. * Di awal karena menemukan cocok dengan seluruh jalur.

$ find . -regextype egrep -regex '.*[a-f0-9\-]{36}\.jpg$'

temukan versi

$ find --version
find (GNU findutils) 4.6.0
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION 
FTS(FTS_CWDFD) CBO(level=2)
binbjz
sumber
6

Anda harus menggunakan jalur direktori absolut ketika menerapkan instruksi temukan dengan ekspresi reguler. Dalam contoh Anda, the

find . -regex "[a-f0-9\-]\{36\}\.jpg"

harus diubah menjadi

find . -regex "./[a-f0-9\-]\{36\}\.jpg"

Di sebagian besar sistem Linux, beberapa disiplin dalam ekspresi reguler tidak dapat dikenali oleh sistem itu, jadi Anda harus secara eksplisit menunjukkan -regexty seperti

find . -regextype posix-extended -regex "[a-f0-9\-]\{36\}\.jpg"
Menyenangkan
sumber