Apakah mungkin menggunakan find
perintah untuk menemukan semua file "non-biner" dalam direktori? Inilah masalah yang saya coba selesaikan.
Saya telah menerima arsip file dari pengguna windows. Arsip ini berisi kode sumber dan file gambar. Sistem build kami tidak cocok dengan file yang memiliki ujung baris windows. Saya memiliki program command line ( flip -u
) yang akan membalik akhir baris antara * nix dan windows. Jadi, saya ingin melakukan sesuatu seperti ini
find . -type f | xargs flip -u
Namun, jika perintah ini dijalankan terhadap file gambar, atau file media biner lainnya, itu akan merusak file. Saya menyadari bahwa saya dapat membuat daftar ekstensi file dan memfilternya, tetapi saya lebih suka memiliki sesuatu yang tidak bergantung pada saya untuk menjaga agar daftar itu tetap mutakhir.
Jadi, apakah ada cara untuk menemukan semua file non-biner di pohon direktori? Atau adakah solusi alternatif yang harus saya pertimbangkan?
file
utilitas di suatu tempat di skrip / pipa Anda untuk mengidentifikasi apakah file tersebut adalah data atau teksJawaban:
Saya akan menggunakan
file
dan menyalurkan output ke grep atau awk untuk menemukan file teks, kemudian ekstrak hanya bagian nama file darifile
output dan pipa yang ke xargs.sesuatu seperti:
Perhatikan bahwa grep mencari 'teks ASCII' dan bukan 'teks' apa pun - Anda mungkin tidak ingin mengacaukan dokumen Rich Text atau unicode file teks dll.
Anda juga dapat menggunakan
find
(atau apa pun) untuk menghasilkan daftar file untuk diperiksa denganfile
:The
-d'\n'
argumen untuk xargs membuat xargs memperlakukan setiap input sebagai argumen yang terpisah, sehingga katering untuk nama file dengan spasi dan karakter bermasalah lainnya. yaitu itu alternatifxargs -0
ketika sumber input tidak atau tidak dapat menghasilkan output yang NULL dipisahkan (sepertifind
's-print0
pilihan). Menurut changelog, xargs mendapat-d
/--delimiter
opsi pada Sep 2005 jadi harus di setiap distro linux yang tidak kuno (saya tidak yakin, itulah sebabnya saya memeriksa - Saya hanya samar-samar ingat itu adalah tambahan "baru").Perhatikan bahwa umpan baris adalah karakter yang valid dalam nama file, jadi ini akan rusak jika ada nama file yang memiliki umpan baris di dalamnya. Untuk pengguna unix tipikal, ini gila secara patologis, tetapi tidak pernah terdengar jika file tersebut berasal dari Mac atau mesin Windows.
Perhatikan juga bahwa
file
itu tidak sempurna. Ini sangat baik dalam mendeteksi tipe data dalam file tetapi kadang-kadang bisa membingungkan.Saya telah menggunakan banyak variasi metode ini berkali-kali di masa lalu dengan kesuksesan.
sumber
file
menampilkanEnglish text
daripadaASCII text
pada sistem Solaris saya, jadi saya memodifikasi bagian itu sesuai. Juga, saya digantiawk -F: '{print $1}'
dengan yang setaracut -f1 -d:
.grep -I
menyaring binaritext
harus cukup. Ini juga akan mengambilfile
deskripsi sepertiASCII Java program text
atauHTML document text
atautroff or preprocessor input text
.ASCII text
menghindari mengacaukan RTF.Tidak. Tidak ada yang istimewa tentang file biner atau non-biner. Anda dapat menggunakan heuristik seperti 'hanya berisi karakter dalam 0x01-0x7F', tetapi itu akan memanggil file teks dengan file biner karakter non-ASCII, dan file biner file teks yang tidak beruntung.
Sekarang, setelah Anda mengabaikan itu ...
file zip
Jika berasal dari pengguna Windows Anda sebagai file zip, format zip mendukung penandaan file sebagai biner atau teks dalam arsip itu sendiri. Anda dapat menggunakan
-a
opsi unzip untuk memperhatikan ini dan mengonversi. Tentu saja, lihat paragraf pertama untuk alasan ini mungkin bukan ide yang baik (program zip mungkin telah menebak dengan salah ketika membuat arsip).zipinfo akan memberi tahu Anda file mana yang biner (b) atau teks (t) dalam daftar zipfile-nya.
file lain
Perintah file akan melihat file dan mencoba mengidentifikasinya. Secara khusus, Anda mungkin akan menemukan
-i
opsi (tipe output MIME) berguna; hanya mengonversi file dengan jenis teks / *sumber
Solusi umum untuk hanya memproses file non-biner dalam
bash
menggunakanfile -b --mime-encoding
:Saya menghubungi penulis utilitas file dan dia menambahkan
-00
paramter bagus di versi 5.26 (dirilis 2016-04-16, misalnya di Arch saat ini dan Ubuntu 16.10) yang mencetakfile\0result\0
untuk beberapa file sekaligus, dengan cara ini Anda dapat melakukan misalnya:(Bagian
awk
ini untuk menyaring setiap file yang bukan non-biner.ORS
Adalah pemisah keluaran.)Dapat juga digunakan dalam satu lingkaran saja:
Berdasarkan ini dan sebelumnya saya membuat
bash
skrip kecil untuk memfilter file biner yang menggunakan metode baru menggunakan-00
parameterfile
dalam versi yang lebih baru dan jatuh kembali ke metode sebelumnya pada versi yang lebih lama:Atau di sini yang lebih POSIX-y, tetapi membutuhkan dukungan untuk
sort -V
:sumber
Jawaban yang diterima tidak menemukan semuanya untuk saya. Berikut ini adalah contoh menggunakan grep
-I
untuk mengabaikan binari, dan mengabaikan semua file yang tersembunyi ...Ini dia digunakan dalam aplikasi praktis: dos2unix
https://unix.stackexchange.com/a/365679/112190
sumber
Jawaban Cas baik, tetapi mengasumsikan nama file yang waras ; khususnya diasumsikan bahwa nama file tidak akan mengandung baris baru.
Tidak ada alasan kuat untuk membuat asumsi ini di sini, karena cukup sederhana (dan sebenarnya lebih bersih menurut saya) untuk menangani kasus itu dengan benar juga:
The
find
perintah saja memanfaatkan fitur POSIX yang ditentukan . Menggunakan-exec
untuk menjalankan perintah sewenang-wenang karena tes boolean sederhana, kuat (menangani nama file aneh dengan benar), dan lebih portabel daripada-print0
.Faktanya, semua bagian dari perintah ditentukan oleh POSIX kecuali untuk
flip
.Catatan yang
file
tidak menjamin keakuratan hasil yang dikembalikan. Namun, dalam praktiknya memahami "teks ASCII" dalam outputnya cukup dapat diandalkan.(Mungkin mungkin melewatkan beberapa file teks, tetapi sangat sangat tidak mungkin untuk mengidentifikasi file biner sebagai "teks ASCII" dan memotongnya — jadi kami melakukan kesalahan).
sumber
calls
bisa sangat lambat, misalnya untuk video itu akan memberi tahu Anda semua tentang pengkodean.-
.file
, dapat mengambil beberapa file sebagai argumen.find
perintah akan awalan./
ke nama file apa pun yang diteruskan ke perintah shell; (3) Menggunakangrep
sebagai tes padafile
output perintah tunggal pada satu waktu adalah satu-satunya cara POSIX yang bisa saya lihat untuk menjamin penanganan nama file yang benar yang mungkin berisi baris baru.file
mendukung--mime-encoding
flag dan--
separator, yang keduanya tidak dijamin oleh POSIX .Ini akan menemukan semua file biasa (
-type f
) di direktori saat ini (atau di bawah) yanggrep
dianggap tidak kosong dan non-biner.Ini digunakan
grep -I
untuk membedakan antara file biner dan non-biner. The-I
bendera dan akan menyebabkangrep
untuk keluar dengan status keluar non-nol ketika mendeteksi bahwa file biner. File "biner", menurutnyagrep
, adalah file yang berisi karakter di luar rentang ASCII yang dapat dicetak.The
-q
pilihan untukgrep
akan menyebabkan ia berhenti dengan status nol keluar jika pola yang diberikan ditemukan, tanpa memancarkan data. Pola yang kami gunakan adalah satu titik, yang akan cocok dengan karakter apa pun.Jika file ditemukan non-biner dan jika mengandung setidaknya satu karakter, nama file tersebut dicetak.
Jika Anda merasa berani, Anda dapat menghubungkannya
flip -u
juga:sumber
Coba ini :
Dimana argumennya
grep '[^ -~]'
adalah'[^<tab><space>-~]'
.Jika Anda mengetikkannya pada baris perintah shell, ketikkan Ctrl+ Vsebelumnya Tab. Dalam editor, seharusnya tidak ada masalah.
'[^<tab><space>-~]'
akan cocok dengan karakter apa pun yang bukan teks ASCII (carriage return diabaikan olehgrep
).-L
hanya akan mencetak nama file file yang tidak cocok-Z
akan menampilkan nama file yang dipisahkan dengan karakter nol (untukxargs -0
)sumber
grep -P
(jika tersedia)\t
tersedia. Atau, gunakan terjemahan lokal jika shell mendukungnya:$'\t'
(bash
danzsh
lakukan).Solusi alternatif:
Perintah dos2unix akan mengubah akhir baris dari Windows CRLF ke Unix LF, dan secara otomatis melewatkan file biner. Saya menerapkannya secara rekursif menggunakan:
sumber
dos2unix
dapat menggunakan beberapa nama file sebagai argumen, jauh lebih efisien untuk melakukannyafind . -type f -exec dos2unix {} +
sudo find / (-type f -and -path '* / git / *' -iname 'README') -exec grep -liI '100644 \ | 100755' {} \; -exec flip -u {} \;
i. (-type f -and -path '* / git / *' -iname 'README'): mencari file dalam jalur yang berisi nama git dan file dengan nama README. Jika Anda tahu folder dan nama file tertentu yang akan dicari, akan berguna.
Perintah ii.-exec menjalankan perintah pada nama file yang dihasilkan oleh find
aku aku aku.\; menunjukkan akhir dari perintah
iv. {} adalah output dari file / nama pengguna yang ditemukan dari pencarian pencarian sebelumnya
v. Beberapa perintah dapat dijalankan selanjutnya. Dengan menambahkan -exec "command" \; seperti dengan -exec flip -u \;
vii.grep
Anda dapat mengkloning direktori tes ini dan mencobanya: https://github.com/alphaCTzo7G/stackexchange/tree/master/linux/findSolution204092017
jawaban lebih rinci di sini: https://github.com/alphaCTzo7G/stackexchange/blob/master/linux/findSolution204092017/README.md
sumber