Saya memiliki daftar file yang ingin saya periksa apakah ada di sistem file saya. Saya berpikir untuk melakukan ini menggunakan find
seperti pada:
for f in $(cat file_list); do
find . -name $f > /dev/null || print $f
done
(menggunakan zsh
) tetapi itu tidak berfungsi karena find
tampaknya keluar 0
atau tidak menemukan file. Saya kira saya bisa melewatinya melalui beberapa tes lain yang menguji untuk melihat apakah find
menghasilkan output apa pun (mentah tapi efektif untuk menggantikan > /dev/null
dengan |grep ''
) tetapi ini terasa seperti menggunakan troll untuk menangkap seekor kambing (bangsa lain mungkin mengatakan sesuatu tentang palu godam dan kenari ).
Apakah ada cara untuk memaksa find
saya memberi saya nilai keluar yang bermanfaat? Atau setidaknya untuk mendapatkan daftar file-file yang tidak ditemukan? (Saya bisa membayangkan yang terakhir ini mungkin lebih mudah dengan beberapa pilihan penghubung logis yang licik, tetapi saya tampaknya selalu terikat dalam simpul ketika saya mencoba mengetahuinya.)
Latar Belakang / Motivasi: Saya memiliki cadangan "master" dan saya ingin memeriksa bahwa beberapa file di mesin lokal saya ada di cadangan master saya sebelum menghapusnya (untuk membuat sedikit ruang). Jadi saya membuat daftar file, ssh
mengeditnya ke mesin master, dan kemudian bingung mencari cara terbaik untuk menemukan file yang hilang.
locate
.locate
tidak menunjukkan status filesystem saat ini, bisa jadi satu hari, atau bahkan berumur seminggu. Itu cocok sebagai basis untuk menguji cadangan.Jawaban:
find
menganggap tidak menemukan kasus khusus keberhasilan (tidak ada kesalahan terjadi). Cara umum untuk menguji apakah file cocok dengan beberapafind
kriteria adalah dengan menguji apakah outputfind
kosong. Untuk efisiensi yang lebih baik ketika ada file yang cocok, gunakan-quit
pada GNU temukan untuk membuatnya berhenti pada pertandingan pertama, atauhead
(head -c 1
jika tersedia, jika tidakhead -n 1
yang merupakan standar) pada sistem lain untuk membuatnya mati karena pipa yang rusak daripada menghasilkan output yang panjang.Di bash ≥4 atau zsh, Anda tidak perlu
find
perintah eksternal untuk pencocokan nama sederhana: Anda dapat menggunakan**/$name
. Versi bash:Versi Zsh dengan prinsip serupa:
Atau inilah cara yang lebih pendek namun lebih samar untuk menguji keberadaan file yang cocok dengan suatu pola. Kualifikasi glob
N
membuat output kosong jika tidak ada kecocokan,[1]
hanya mempertahankan kecocokan pertama, dane:REPLY=true:
mengubah setiap kecocokan untuk diperluas menjadi1
bukan nama file yang cocok. Jadi**/"$name"(Ne:REPLY=true:[1]) false
perluastrue false
jika ada kecocokan, atau hanyafalse
jika tidak ada kecocokan.Akan lebih efisien untuk menggabungkan semua nama Anda menjadi satu pencarian. Jika jumlah pola tidak terlalu besar untuk batas panjang sistem Anda pada baris perintah, Anda dapat menggabungkan semua nama dengan
-o
, melakukanfind
panggilan tunggal , dan memposting proses. Jika tidak ada nama yang mengandung karakter meta shell (sehingga namanya jugafind
pola), berikut adalah cara untuk pasca-proses dengan awk (belum diuji):Pendekatan lain adalah dengan menggunakan Perl dan
File::Find
, yang membuatnya mudah untuk menjalankan kode Perl untuk semua file dalam direktori.Pendekatan alternatif adalah membuat daftar nama file di kedua sisi dan bekerja pada perbandingan teks. Versi Zsh:
sumber
zsh
solusinya dengan**
sintaks. Ini adalah solusi yang sangat sederhana dan sementara itu mungkin bukan yang paling efisien dalam hal mesin , itu mungkin yang paling efisien dalam hal saya benar-benar mengingatnya! Juga, solusi pertama di sini menjawab pertanyaan yang sebenarnya karena memutarfind
ke sesuatu di mana kode keluar membedakan "Saya mendapat kecocokan" dari "Saya tidak mendapatkan kecocokan".Anda dapat menggunakanstat
untuk menentukan apakah ada file di sistem file.Anda harus menggunakan fungsi shell bawaan untuk menguji apakah file ada.
"Tes" bersifat opsional dan skrip akan benar-benar berfungsi tanpanya, tetapi saya membiarkannya agar dapat dibaca.
Sunting: Jika Anda benar-benar tidak memiliki pilihan selain bekerja untuk daftar nama file tanpa path, saya sarankan Anda membuat daftar file sekali dengan find, kemudian beralih dengan grep untuk mencari tahu file mana yang ada.
Perhatikan bahwa:
sumber
Pendekatan pertama dan sederhana, bisa berupa:
a) urutkan daftar file Anda:
untuk menemukan yang hilang, atau
untuk menemukan kecocokan
Kekurangan:
find dapat mencari beberapa file sekaligus, dengan beberapa persiapan:
temukan -nama a.file -atau -nama -b.file -atau -nama c.file ...
Bisakah lokasi menjadi pilihan? Sekali lagi, daftar file yang diasumsikan diasumsikan:
Pencarian untuk foo.bar tidak akan cocok dengan file a foo.ba, atau oo.bar dengan --regexp-construct (tidak akan di-confue oleh regex tanpa p).
Anda dapat menentukan basis data spesifik untuk mencari, dan Anda harus memperbaruinya sebelum mencari, jika Anda membutuhkan hasil terbaru.
sumber
Saya pikir ini bisa bermanfaat juga.
Ini adalah solusi satu baris, jika Anda memilih "daftar" Anda menjadi file nyata yang ingin Anda sinkronkan dengan folder lain:
untuk membantu membaca:
contoh ini tidak termasuk file cadangan "* ~" dan batasan untuk tipe file biasa "-type f"
sumber
Mungkin?
sumber
Mengapa tidak membandingkan panjang daftar permintaan dengan panjang daftar hasil?
sumber