Apa perintah baris perintah Linux yang dapat mengidentifikasi file seperti itu?
AFAIK find
perintah (atau grep
) hanya bisa cocok dengan string tertentu di dalam file teks. Tapi saya ingin mencocokkan seluruh konten, yaitu saya ingin melihat file mana yang cocok dengan ekspresi reguler \0+
, mengabaikan karakter garis akhir . Mungkin find . cat | grep
idiom bisa bekerja, tapi saya tidak tahu bagaimana membuat garis mengabaikan grep (dan memperlakukan file sebagai biner).
Latar Belakang: Setiap beberapa hari, ketika laptop saya macet, partisi btrf saya kehilangan informasi: file yang dibuka untuk penulisan mendapat isinya diganti dengan nol (ukuran file tetap lebih atau kurang utuh). Saya menggunakan sinkronisasi dan saya tidak ingin menyebarkan file palsu ini: Saya perlu cara untuk mengidentifikasi mereka sehingga saya dapat mengambilnya dari cadangan.
sumber
-v
opsi untuk melakukan grep: memfilter semua file yang memiliki byte 1 hingga 255.Jawaban:
Anda dapat
grep
untuk karakter ␀ menggunakan mode Perl regex:Jadi Anda bisa menggunakan ini:
sumber
GNU grep 2.5.4
. Terlepas dari apakah saya menggunakan--binary-files=text
atau--binary-files=binary
, itu memberikantrue
hasil untuk semua nilai data yang tidak kosong, misalnya."\0\0"
,"\0x\0"
,"abcd"
... Kode tepat saya digunakan adalah:for typ in binary text ;do for dat in '\0\0' '\0x\0' 'abcd' '' ;do printf "$dat" >f; grep --binary-files=$typ -P '[^\0]' f >/dev/null && echo true || echo false; done; done
GNU grep) 2.10
. Versi yang lebih baru ini memang memberikan hasil yang diharapkan ... jadi, +1 terlambatprintf '\0\n\0\0\n\n' > file
atauprintf '\n' > file
untuk hal itu.\0
dan\n
(bahkan nol dari keduanya) akan cocok.Saya setuju dengan apa yang dikatakan D_Bye tentang menemukan akar masalah.
Pokoknya untuk memeriksa apakah suatu file hanya berisi
\0
dan / atau\n
Anda dapat menggunakantr
:Yang mengembalikan 0 untuk file null / baris baru dan kosong.
sumber
tr -d '\0\n'
memecahkan masalah baris baru, yang kemudian hanya meninggalkan masalah (?) file kosong yang tercantum dalam output ... Itu memproses setiap byte setiap file meskipun (yang mungkin atau mungkin tidak menjadi masalah) +1Saya menduga file-file itu jarang, yaitu mereka tidak memiliki ruang disk yang dialokasikan untuk mereka, mereka hanya menentukan ukuran file (
du
akan melaporkan 0 untuk mereka).Dalam hal ini, dengan GNU find, Anda dapat melakukannya (dengan asumsi tidak ada jalur file yang mengandung karakter baris baru):
sumber
du
akan mencegah dari menggaruk konten setiap file dalam sistem file, sehingga seluruh prosedur tidak akan memakan waktu 30 menit untuk menyelesaikan.printf %b
atas melaporkan apa yangdu
akan dilaporkan)-size +0
menjadi-size +1
file dengan panjang nol tidak termasuk dalam hasil. File-file yang berisi\n
path mereka akan menyebabkan masalah untuk perintah ini.-size +0
adalah untuk ukuran yang benar-benar lebih besar dari 0.-size +1
akan untuk ukuran yang benar-benar lebih besar dari 512. Batasan baris baru telah disebutkan.-size +1
, Anda memang benar. Saya sudah memperbaiki jawaban saya . :-)Berikut ini adalah program python kecil yang dapat melakukannya:
Dan beraksi:
Anda dapat memeriksa beberapa file dengan menggunakan find ini
-exec
,xargs
, GNUparallel
, dan program-program serupa. Atau, ini akan mencetak nama file yang perlu ditangani:Ingatlah bahwa jika Anda akan meneruskan output ini ke program lain, nama file dapat berisi baris baru, jadi Anda harus membatasi itu secara berbeda (sesuai, dengan
\0
).Jika Anda memiliki banyak file, akan lebih baik menggunakan opsi untuk pemrosesan paralel, karena ini hanya membaca satu file pada satu waktu.
sumber
/etc/nologin
,~/.hushlogin
,.nomedia
, ...) yang salah diidentifikasi oleh jawaban ini.Temukan file yang hanya berisi karakter null '\ 0' dan karakter baris baru '\ n'.
The
q
di sed penyebab setiap file mencari untuk segera berhenti setelah menemukan karakter non-null dalam garis.Buat file uji
keluaran
sumber
-print0
argumen itu tampaknya hilangfind
atauIFS=
bagian itu kacau. Apa pembatas yang dimaksud?Ini satu-kapal adalah cara yang paling efisien untuk menemukan 100% file nul menggunakan GNU
find
,xargs
dangrep
(dengan asumsi yang terakhir dibangun dengan dukungan PCRE):Keuntungan dari metode ini dibandingkan jawaban lain yang disediakan adalah:
Permission denied
peringatan.grep
akan berhenti membaca data dari file setelah menemukan byte non-nul (LC_ALL=C
digunakan untuk memastikan setiap byte diartikan sebagai karakter ).grep
proses secara efisien memeriksa banyak file.-
ditangani dengan benar.Melewati
-Z
opsi kegrep
dan menggunakanxargs -r0 ...
memungkinkan tindakan lebih lanjut untuk dilakukan pada file nul 100% (misalnya: pembersihan):Saya juga merekomendasikan menggunakan
find
opsi-P
untuk menghindari symlink berikut, dan-xdev
untuk menghindari melintasi sistem file (misalnya: mount jarak jauh, bagan perangkat, bind mounts, dll).Untuk mengabaikan karakter garis akhir , varian berikut harus berfungsi (walaupun saya pikir ini bukan ide yang bagus):
Menyatukan semuanya, termasuk menghapus file yang tidak diinginkan (100% nul / karakter baris baru) untuk mencegahnya dicadangkan:
Saya tidak menyarankan untuk memasukkan file kosong (nol byte), mereka sering ada untuk tujuan yang sangat spesifik .
sumber
\0
dengan lubang 900MB di dalamnya) dan menyajikan waktu dari hasil. Jika Anda melakukannya dengan cara patokan meyakinkan untuk Anda, kemungkinan besar itu akan meyakinkan kita semua-P
adalah default dalamfind
. Jika Anda ingin mengikuti symlink, ini-L
/-follow
. Anda akan menemukan POSIX bahkan tidak menentukan opsi untukfind
(meskipun POSIX adalah orang yang memperkenalkan -P / -H / -L untuk beberapa perintah).Untuk menggunakan sed GNU Anda dapat menggunakan
-z
opsi, yang mendefinisikan sebuah baris sebagai string yang diakhiri tanpa nol dan cocok dengan dan menghapus baris kosong seperti:Peralihan perintah kepala hanyalah sebuah optimasi.
sumber
Python
File tunggal
Tentukan alias:
Menguji:
Banyak file
Temukan semua file biner secara rekursif:
Untuk menemukan semua file non-biner, ubah
&&
dengan||
.sumber