Mulai dari (perhatikan wildcard sebelum dan sesudah "beberapa teks")
find . -type f -name '*some text*'
bagaimana kita bisa mengecualikan / mengabaikan semua file dan direktori tersembunyi?
Saya sudah googling terlalu lama , menemukan beberapa -prune dan! (tanda seru) parameter, tetapi tidak ada contoh pas (dan pelit) yang hanya bekerja .
Perpipaan |
untuk grep
menjadi pilihan dan saya juga menyambut contoh itu; tetapi terutama saya tertarik pada satu-liner singkat (atau beberapa satu-liner yang berdiri sendiri, menggambarkan berbagai cara untuk mencapai tujuan baris perintah yang sama) hanya menggunakan find
.
ps: Temukan file di linux dan kecualikan direktori spesifik yang tampaknya terkait erat, tetapi a) belum diterima dan b) terkait-tetapi-berbeda-dan-berbeda, tetapi c) dapat memberikan inspirasi dan membantu menunjukkan kebingungan!
Sunting
find . \( ! -regex '.*/\..*' \) -type f -name "whatever"
, bekerja. Regex mencari "apa saja, lalu garis miring, lalu titik, lalu apa saja" (yaitu semua file dan folder tersembunyi termasuk subfoldernya), dan "!" meniadakan regex.
sumber
Jawaban:
Ini mencetak semua file yang merupakan keturunan dari direktori Anda, melewatkan file dan direktori tersembunyi:
Jadi, jika Anda mencari file dengan
some text
namanya, dan Anda ingin melewati file dan direktori tersembunyi, jalankan:Penjelasan:
The
-path
pilihan menjalankan pemeriksaan pola terhadap seluruh string path.*
adalah wildcard,/
adalah pemisah direktori,\.
adalah sebuah titik (harus diloloskan untuk menghindari makna khusus), dan*
merupakan wildcard lainnya.-not
artinya jangan pilih file yang cocok dengan tes ini.Saya tidak berpikir itu
find
cukup pintar untuk menghindari mencari direktori tersembunyi secara rekursif dalam perintah sebelumnya, jadi jika Anda membutuhkan kecepatan, gunakan-prune
saja, seperti ini:sumber
-print
di akhir! Juga, tidak yakin apakah-name '\.*' would be more efficient instead of
-path` (karena path sedang mencari subpath, tetapi ini akan dipangkas).
konteks ini?find
berarti direktori saat ini:find
akan melihat semua file dan direktori di bawah direktori saat ini. Argumen sesudahnyapath
adalah ekspresi reguler, di mana sebuah titik biasanya berarti "karakter apa saja", untuk menjadikannya sebuah titik literal kita harus menghindarinya dengan backslash. Argumen setelah-name
itu bukanlah ekspresi reguler, tetapi memperluas wildcard seperti?
dan*
seperti shell..
memiliki makna khusus..
. Sejauh yang saya tahu, hanya ini perlu melarikan diri:*
,?
, dan[]
.Ini adalah salah satu dari sedikit cara mengecualikan file-file dot yang juga berfungsi dengan benar di BSD, Mac dan Linux:
$PWD
cetak path lengkap ke direktori saat ini sehingga path tidak dimulai./
-name ".*" -prune
cocok dengan semua file atau direktori yang dimulai dengan titik dan kemudian tidak turun-o -print
berarti mencetak nama file jika ungkapan sebelumnya tidak cocok dengan apa pun. Menggunakan-print
atau-print0
menyebabkan semua ekspresi lain tidak dapat mencetak secara default.sumber
-o ... -print
membantu. Untuk penggunaan saya, sekarang saya milikifind ... '!' -name . -name '.*' -prune -o ... -print
, yang lebih nyaman daripada memasukkan $ PWD.Tidak termasuk semua direktori tersembunyi, dan file tersembunyi di bawah $ DIR
sumber
The jawaban saya awalnya diumumkan sebagai "edit" ke pertanyaan awal saya di atas:
find . \( ! -regex '.*/\..*' \) -type f -name "whatever"
, bekerja. Regex mencari "apa saja, lalu garis miring, lalu titik, lalu apa saja" (yaitu semua file dan folder tersembunyi termasuk subfoldernya), dan "!" meniadakan regex.sumber
find . \( ! -regex './\..*' \) -type f -maxdepth 1 -print
Anda tidak perlu menggunakannya
find
untuk itu. Cukup gunakan globstar di shell-nya sendiri, seperti:atau:
di mana
**/
merepresentasikan folder apa pun secara rekursif dan*foo*
file apa pun yang memilikifoo
namanya.Secara default menggunakan
ls
akan mencetak nama file tidak termasuk file dan direktori tersembunyi.Jika Anda tidak mengaktifkan globbing, lakukan dengan
shopt -s globstar
.Catatan: Opsi globbing baru berfungsi di Bash 4, zsh dan shell serupa.
Contoh:
sumber
ls
untuk itu!echo **/*foo*
/
berarti folder, memisahkan direktori dari nama file.*
pada dasarnya mewakili segalanya.@ Flimm's jawaban baik, terutama karena mencegah menemukan turun ke direktori tersembunyi . Saya lebih suka penyederhanaan ini:
Umumnya untuk mengecualikan semua jalur tersembunyi (file biasa, direktori, dll):
Misalnya, menggunakan direktori kerja Anda sebagai titik awal, dan
-name '*some text*'
sebagai ekspresi:Berbeda dengan apa yang disarankan @ Flimm, tidak ada file tersembunyi atau direktori tersembunyi adalah kasus sederhana. The
-path '*/.*'
ekspresi benar untuk setiap jalan (file biasa, direktori, dll) yang memiliki.
segera setelah pemisah file Anda,/
. Jadi baris ini akan memangkas file dan direktori tersembunyi.Mengizinkan file tersembunyi sambil mengecualikan direktori tersembunyi adalah kasus yang membutuhkan filter lebih lanjut. Di sinilah Anda akan memasukkan
-type d
dalam ekspresi sedang dipangkas.Sebagai contoh:
Dalam hal
-type d -path '*/.*'
initrue
hanya untuk direktori, dan hanya direktori yang dipangkas.sumber
find
memiliki sakelar logika yang rapi seperti-and
dan-not
Anda dapat menggunakannya untuk keuntungan Anda untuk menemukan file yang cocok dengan dua aturan seperti:Seperti yang Anda lihat,
find
gunakan dua aturan-name '*hidden_file*'
dan-and \( -not -name ".*" \)
untuk menemukan nama file yang cocok dengan kedua kondisi - nama file denganhidden_file
di dalamnya tetapi tanpa titik awal. Catat garis miring di depan tanda kurung - mereka digunakan untuk mendefinisikan tanda kurung sebagaifind
argumen, bukan mendefinisikan subkulit (yang artinya tanda kurung dinyatakan tanpa garis miring)sumber
Catatan:
.
: folder saat ini-maxdepth 1
untuk mencari secara rekursif-type f
: cari file, bukan direktori (d
)-not -path '*/\.*'
: jangan kembali.hidden_files
sed 's/^\.\///g'
: hapus yang diawali./
dari daftar hasilsumber