Saya ingin mencari file yang diakhiri dengan _peaks.bed
, tetapi mengecualikan file di folder tmp
dan scripts
.
Perintah saya seperti ini:
find . -type f \( -name "*_peaks.bed" ! -name "*tmp*" ! -name "*scripts*" \)
Tapi itu tidak berhasil. File di dalam tmp
dan script
folder akan tetap ditampilkan.
Apakah ada yang punya ide tentang ini?
_peaks.bed
.find
, tetapi karena pertanyaannya diberi tag Linux, itu tidak menjadi masalah. Jawaban yang bagus..
pada prompt pencarian awal, Anda harus menggunakannya di setiap jalur yang Anda kecualikan. Pencocokan jalur cukup ketat, tidak melakukan pencarian kabur. Jadi jika Anda menggunakannyafind / -type f -name *.bed" ! -path "./tmp/"
tidak akan berhasil. Anda harus! -path "/tmp"
membuatnya bahagia.$ ! -path "./directory/*"
-prune
daripada memeriksa setiap file di pohon." Jika direktori Anda yang dikecualikan berjalan sangat dalam atau memiliki banyak file dan Anda peduli dengan kinerjanya, gunakan-prune
opsi sebagai gantinya.Inilah salah satu cara Anda dapat melakukannya ...
find . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)"
sumber
find
, bukan hanya dengan GNUfind
. Namun, pertanyaannya adalah men-tag Linux sehingga tidak kritis.Menggunakan
find \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
atau
find \( -path "./tmp" -o -path "./scripts" \) -prune -false -o -name "*_peaks.bed"
atau
find \( -path "./tmp" -path "./scripts" \) ! -prune -o -name "*_peaks.bed"
Urutan itu penting. Ini mengevaluasi dari kiri ke kanan. Selalu mulai dengan pengecualian jalur.
Penjelasan
Jangan gunakan
-not
(atau!
) untuk mengecualikan seluruh direktori. Gunakan-prune
. Seperti yang dijelaskan di manual:dan di GNU temukan manual:
Memang, jika Anda menggunakan
-not -path "./pathname"
, find akan mengevaluasi ekspresi untuk setiap node di bawah"./pathname"
.menemukan ekspresi hanyalah evaluasi kondisi.
\( \)
- Operasi grup (Anda dapat menggunakan-path "./tmp" -prune -o -path "./scripts" -prune -o
, tetapi lebih bertele-tele).-path "./script" -prune
- jika-path
kembali benar dan adalah sebuah direktori, kembali benar untuk direktori tersebut dan jangan tidak turun ke dalamnya.-path "./script" ! -prune
- dievaluasi sebagai(-path "./script") AND (! -prune)
. Ini mengembalikan "selalu benar" dari prune menjadi selalu salah. Ini menghindari pencetakan"./script"
sebagai korek api.-path "./script" -prune -false
- karena-prune
selalu mengembalikan nilai true, Anda dapat mengikutinya dengan-false
melakukan hal yang sama dari!
.-o
- ATAU operator. Jika tidak ada operator yang ditentukan di antara dua ekspresi, defaultnya adalah operator AND.Oleh karena itu,
\( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
diperluas menjadi:[ (-path "./tmp" OR -path "./script") AND -prune ] OR ( -name "*_peaks.bed" AND print )
Cetakan penting di sini karena tanpa itu diperluas menjadi:
{ [ (-path "./tmp" OR -path "./script" ) AND -prune ] OR (-name "*_peaks.bed" ) } AND print
-print
ditambahkan oleh find - itulah sebabnya sebagian besar waktu, Anda tidak perlu menambahkannya dalam ekspresi Anda. Dan karena-prune
mengembalikan nilai true, itu akan mencetak "./script" dan "./tmp".Hal ini tidak perlu dilakukan di tempat lain karena kami beralih
-prune
untuk selalu mengembalikan false.Petunjuk: Anda dapat menggunakan
find -D opt expr 2>&1 1>/dev/null
untuk melihat bagaimana itu dioptimalkan dan diperluas,find -D search expr 2>&1 1>/dev/null
untuk melihat jalur mana yang diperiksa.sumber
Cobalah sesuatu seperti
find . \( -type f -name \*_peaks.bed -print \) -or \( -type d -and \( -name tmp -or -name scripts \) -and -prune \)
dan jangan terlalu terkejut jika saya salah paham. Jika tujuannya adalah seorang exec (bukan print), gantikan saja.
sumber
bagi saya, solusi ini tidak berfungsi pada perintah exec dengan find, tidak benar-benar tahu mengapa, jadi solusi saya adalah
find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;
Penjelasan: sama seperti sampson-chen satu dengan tambahan
-prune - abaikan jalur prosedural ...
-o - Kemudian jika tidak ada hasil yang cocok, (pangkas direktori dan cetak hasil yang tersisa)
18:12 $ mkdir a b c d e 18:13 $ touch a/1 b/2 c/3 d/4 e/5 e/a e/b 18:13 $ find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \; gzip: . is a directory -- ignored gzip: ./a is a directory -- ignored gzip: ./b is a directory -- ignored gzip: ./c is a directory -- ignored ./c/3: 0.0% -- replaced with ./c/3.gz gzip: ./d is a directory -- ignored ./d/4: 0.0% -- replaced with ./d/4.gz gzip: ./e is a directory -- ignored ./e/5: 0.0% -- replaced with ./e/5.gz ./e/a: 0.0% -- replaced with ./e/a.gz ./e/b: 0.0% -- replaced with ./e/b.gz
sumber
find . -path ./scripts -prune -name '*_peaks.bed' -type f
,. Tidak yakin bagaimana mengecualikan beberapa direktori. Ini juga mencantumkan direktori tingkat atas yang dikecualikan meskipuntype
ditentukan. Mengecualikan melalui Grep tampaknya lebih mudah kecuali Anda ingin menggunakan prune untuk mempercepat operasi pencarian.Anda dapat mencoba di bawah ini:
find ./ ! \( -path ./tmp -prune \) ! \( -path ./scripts -prune \) -type f -name '*_peaks.bed'
sumber