O'zlarining tarkibida 100% NUL belgilar bilan fayllarni qanday topish mumkin?

Bunday fayllarni identifikatsiya qiladigan Linux komandasi buyrug'i nima?

AFAIK find buyrug'i (yoki grep ) faqat matni bilan mos keladigan matnni kiritishi mumkin. Lekin men barcha tarkibga mos kelishini xohlayman, ya'ni qaysi fayllar muntazam ravishda \ 0 + ifodasi bilan mos kelishini ko'rishni istayman, satr oxiridagi belgilar (lar) ni e'tiborsiz qoldirib, . Ehtimol toping. mushuklar | grep iborasi ishlashi mumkin edi, ammo grepni qanday qilib chetga surib qo'yishni bilmayman (va faylni ikkitomonlama deb hisoblang).

Tarix: Bir necha kun ichida, mening tizza kompyuterimni ishga tushirganimda, mening btrfs bo'limim ma'lumotni yo'qotadi: yozuv uchun ochilgan fayllar tarkibini nol bilan o'zgartiradi (fayl hajmi kattaroq yoki ozgina saqlanib qoladi). Sinxronizatsiya xizmatidan foydalanaman va bu soxta fayllarni tarqalishini xohlamayman: ularni zahira nusxasidan olishim uchun ularni aniqlash uchun kerak.

13
@D_Bugun, bu yaxshi fikr, lekin hozirga qadar juda uzoqqa bormadi: [http://hex.stackexchange.com/questions/57894/untraceable-stability-problem-of-3-6-8 -kernel-on-asus-p53e] "title =" asus p53e% 5d ustida 3 6 8 yadrosi saqlanadigan barqarorligi muammosi "> unix.stackexchange.com/questions/57894/…
qo'shib qo'ydi muallif Robin Weston, manba
grep uchun -v parametrini ko'rib chiqdingiz: 1 dan 255 gachasi baytlarga ega bo'lgan barcha fayllarni filtrlash.
qo'shib qo'ydi muallif Mike, manba
@D_Bye Bu to'g'ri bo'lsa-da, so'rovchi kontekstni o'rnatadigan Unix SE da precedents mavjud.
qo'shib qo'ydi muallif Eric Platon, manba
Menimcha, bu raqamli noldan ko'ra NULL belgilar haqida.
qo'shib qo'ydi muallif gertvdijk, manba
sizda raqamli nollarga ega bo'lgan fayllarni nazarda tutasizmi?
qo'shib qo'ydi muallif Rahul Patil, manba
@AdamRyczkowski - oh, men allaqachon ustida ishlayotganingizni tushunmadim - uzr so'rayman.
qo'shib qo'ydi muallif frerechanel, manba
Bu yerga qadam qo'yaylik. Bir necha kun ichida, tizza kompyuteringiz muzlatib qo'yilganda? Nima uchun bu ni tuzatishga urinmayapmiz, bu erda haqiqiy muammolar bormi?
qo'shib qo'ydi muallif frerechanel, manba

6 javoblar

Perl regex rejimidan foydalanib ␀ belgilar uchun grep mumkin:

$ echo -ne "\0\0" > nul.bin
$ echo -ne "\0x\0" > non-nul.bin
$ grep -P "[^\0]" *.bin
Binary file non-nul.bin matches

Shunday qilib, siz quyidagilarni foydalanishingiz mumkin:

for path in *.foo
do
    grep -P "[^\0]" "$path" || echo "$path"
done
10
qo'shib qo'ydi
@ StéphaneChazelas OP "satr oxirigacha belgi (lar) ni e'tiborga olmaslik" deb aytdi. Shunday qilib, faqat \ 0 va \ n belgilaridan (hatto noldan) iborat bo'lgan fayllar ham mos keladi.
qo'shib qo'ydi muallif Bjørn, manba
Keling, yana GNU grep) 2.10 ni sinab ko'rdim. Ushbu keyingi versiya kutilgan natijalarni beradi ... shuning uchun, kechiktirilgan +1
qo'shib qo'ydi muallif Sameer, manba
GNU grep 2.5.4 dan foydalanib kutilmagan natijalarga erishaman. - ikkilik fayllar = matn yoki - ikkilik fayllar = ikkilik dan foydalanmasligimdan qat'iy nazar, barcha nonlar uchun haqiqiy natijasi beradi - ma'lumotlarning bo'sh qadriyatlari, masalan. "\ 0 \ 0" "\ 0x \ 0" , "abcd" ... Men foydalanadigan aniq kod: Ikkilangan matnda yozish uchun '\ 0 \ 0' '\ 0x \ 0' 'abcd' 'dat'ini bajaring; printf "$ dat"> f; grep - binary-files = $ tip -P '[^ \ 0]' f>/dev/null va& echo rost || echo noto'g'ri; bajarildi; bajarilgan
qo'shib qo'ydi muallif Sameer, manba
Bu holatlar uchun printf '\ 0 \ n \ 0 \ 0 \ n \ n'> file yoki printf '\ n'> faylini bilan yaratilgan faylda ishlamay qoladi.
qo'shib qo'ydi muallif Stéphane Chazelas, manba

Men D_Bye muammoning ildizini topish haqida nima deyayotganiga qo'shilaman.

Faylni faqatgina \ 0 va/yoki \ n o'z ichiga olganligini tekshirish uchun uz dan foydalanishingiz mumkin:

Null/newline va bo'sh fayllar uchun 0 qaytib keladi.

5
qo'shib qo'ydi
Bu juda yaxshi ishlaydi. Men o'zimning ishimdan faqat nol uzunlikdagi fayllarni chiqarib tashlashga ishonchim komil bo'lishi kerak edi. Rahmat.
qo'shib qo'ydi muallif Robin Weston, manba
tr -d \\\\\\\\\\\ 'n' yangi satr muammolarini echib tashlaydi, bu esa faqat chiqishda listelenadigan bo'sh fayllar muammosini (?) qoldiradi ... Har bir faylning har bir baytini (Bu muammo bo'lishi mumkin yoki bo'lishi mumkin emas) +1
qo'shib qo'ydi muallif Sameer, manba
Shu bilan birga, bu yangi qatorlarni "bo'sh" deb hisoblaydi.
qo'shib qo'ydi muallif Eric Platon, manba
@ChrisDown: Men javob matnini nima qilganiga aniq tushuntirdim. OX yangi qatorga kiritilgan fayllar bilan nima qilishni istashi aniq emas.
qo'shib qo'ydi muallif Thor, manba
@ Peter.O: Men yangi tilga talabni sog'indim, rahmat. Ushbu yechim juda optimallashtirilmagan va agar u juda ko'p ma'lumotlarga ishlasa, unda mos bo'lmagan baytlarni topishga harakat qiladigan echim bilan yaxshi bo'ladi.
qo'shib qo'ydi muallif Thor, manba

Bu mumkin bo'lgan kichik python dasturi:

import sys
def chunkCheck(fileObject, chunkSize=1024):
    while True:
        data = fileObject.read(chunkSize)
        if not data:
            return False
        if data.strip("\0"):
            return True
sys.exit(chunkCheck(open(sys.argv[1])))

Va amalda:

$ printf '\0\0\0' > file
$ ./onlynulls file && echo "Only nulls" || echo "Non-null characters"
Only nulls
$ printf a >> file
$ ./onlynulls file && echo "Only nulls" || echo "Non-null characters"
Non-null characters

-exec , xargs , GNU parallel va shunga o'xshash dasturlar yordamida bir nechta faylni tekshirishingiz mumkin. Shu bilan bir qatorda, ushbu operatsiyani bajarish kerak bo'lgan fayl nomlarini chop etadi:

files=( file1 file2 )
for file in "${files[@]}"; do
    ./onlynulls "$file" || printf '%s\n' "$file"
done

Shuni esda tutingki, agar siz ushbu dasturning chiqishini boshqa dasturga o'tkazmoqchi bo'lsangiz, fayl nomlari yangi satrlarni o'z ichiga olishi mumkin, shuning uchun uni boshqa tarzda ajratish kerak (mos ravishda, \ 0 ).

Agar sizda ko'p fayllar mavjud bo'lsa, parallel ishlov berish uchun parametrlardan foydalaning, chunki bu faqat bir vaqtning o'zida bitta faylni o'qiydi.

4
qo'shib qo'ydi

Men ushbu fayllar juda siyrak deb o'ylayman, ya'ni, ular uchun ajratilgan disk maydoni yo'q, ular faqat fayl hajmi ( du ) ular uchun hisobot berishadi.

Bunday holatda, GNU bilan topishingiz mumkin, (siz fayl yo'lida yangi satr belgilarini kiritmaslik kerak):

find . -type f -size +0 -printf '%b:%p\n' | grep '^0:' | cut -d: -f2-
4
qo'shib qo'ydi
Yaxshi fikr. Men bu haqda hech o'ylamagan edim. Harakat qilaman. du dan foydalanish fayl tizimidagi har bir faylning tarkibini chizishdan saqlanishiga olib keladi, shuning uchun butun jarayon 30 + daqiqani to'ldirmaydi.
qo'shib qo'ydi muallif Robin Weston, manba
(va printf% b yuqoridagi hisobotlarni bildiradi du )
qo'shib qo'ydi muallif Stéphane Chazelas, manba

Faqat \ '0' va '\ n' satrlari mavjud bo'lgan fayllarni toping sed da q har bir faylni qidirish satrda null bo'lmagan har qanday belgi topib darhol chiqib ketishiga sabab bo'ladi.

find -type f -name 'file-*' |
  while IFS= read -r file ;do 
      out=$(sed -n '1=; /^\x00\+$/d; i non-null
                      ; q' "$file")
      [[ $out == "1" ]] &&  echo "$file"
  done

Sinov fayllarini yarating

> file-empty
printf '%s\n' 'line1' 'line2' 'line3'      > file-with-text           
printf '%4s\n' '' '' xx | sed 's/ /\x00/g' > file-with-text-and-nulls
printf '%4s\n' '' '' '' | sed 's/ /\x00/g' > file-with-nulls-and-newlines
printf '%4s'   '' '' '' | sed 's/ /\x00/g' > file-with-nulls-only

chiqdi

./file-with-nulls-and-newlines
./file-with-nulls-only
2
qo'shib qo'ydi

Python

Bitta fayl

Boshqa taxallusni belgilang:

alias is_binary="Python -c 'import sys; sys.exit(not b\"\x00\" in open(sys.argv[1], \"rb\").read())'"

Sinash:

$ is_binary /etc/hosts; echo $?
1
$ is_binary `which which`; echo $?
0

Ko'p fayl

Barcha ikkilik fayllarni o'z-o'zidan toping:

IS_BINARY='import sys; sys.exit(not b"\x00" in open(sys.argv[1], "rb").read())'
find . -type f -exec bash -c "Python -c '$IS_BINARY' {} && echo {}" \;

To find all non-binary files, change && with ||.

0
qo'shib qo'ydi