Bazı ikili veriler içeren bir metin dosyası nasıl grep edilir?


123

grep iadeleri

İkili dosya test.log eşleşir

Örneğin

echo    "line1 re \x00\r\nline2\r\nline3 re\r\n" > test.log  # in zsh
echo -e "line1 re \x00\r\nline2\r\nline3 re\r\n" > test.log  # in bash
grep re test.log

Keşke sonuç satır1 ve satır3'ü (toplam iki satır) gösterecek.

trGrep'in tekrar çalışmasına izin vermek için yazdırılamayan verileri okunabilir verilere dönüştürmek mümkün müdür ?


İkili bir dosyadan ikili karakterleri filtreleyen ve yalnızca metin karakterlerini (okunabilir) tutan bir program olduğunu lütfen unutmayın. Burada: soft.tahionic.com/download-words_extractor/index.html
InTheNameOfScience

Affedersiniz ama ... eksik değil -ede echokomuta?
Sopalajo de Arrierez

'Zsh' kullanırsanız, -e olmadan tamamdır. "Bash" kullanırsanız, "-e" eklemelisiniz.
Daniel YC Lin

Yanıtlar:


68

Veri dosyasını çalıştırabilirsiniz cat -v, örn.

$ cat -v tmp/test.log | grep re
line1 re ^@^M
line3 re^M

daha sonra önemsizleri çıkarmak için sonradan işlenebilir; bu, trgörev için kullanma hakkındaki sorgunuza en çok benzeyen şeydir.


5
Sorunumu çözdüm. Teşekkürler! İşte man cathakkında -v-v, --show-nonprinting use ^ and M- notation, except for LFD and TAB
söylenenler

Bunun bir boru hattında da çalıştığını unutmayın. Örneğinset | cat -v | grep variable
funroll

1
Grep --text çalışıyorsa neden bunu kullanalım? Bu çok daha karmaşık görünüyor.
Michael Haefele

grep --texther zaman çalışmaz; CTRL + D'ye bir dosya sonlandırıcı olarak saygı duyar. Eğer ikili dosyanızda bu varsa, grep erken çıkacaktır.
Tommy


91

Bunun bir yolu, ikili dosyaları zaten metin olarak ele almaktır, grep --textancak bu, terminalinize ikili bilgilerin gönderilmesine neden olabilir. Çıkış akışını (VT / DEC veya diğerleri gibi) yorumlayan bir terminal çalıştırıyorsanız, bu gerçekten iyi bir fikir değildir.

Alternatif olarak, dosyanızı traşağıdaki komutla gönderebilirsiniz :

tr '[\000-\011\013-\037\177-\377]' '.' <test.log | grep whatever

Bu, boşluk karakterinden daha az olan her şeyi (satırsonu hariç) ve 126'dan büyük her şeyi bir .karaktere dönüştürür ve geriye yalnızca yazdırılabilirleri bırakır.


Her "geçersiz" karakterin farklı bir karakterle değiştirilmesini istiyorsanız, aşağıdaki C programı gibi, klasik bir standart giriş filtresi kullanabilirsiniz:

#include<stdio.h>
int main (void) {
    int ch;
    while ((ch = getchar()) != EOF) {
        if ((ch == '\n') || ((ch >= ' ') && (ch <= '~'))) {
            putchar (ch);
        } else {
            printf ("{{%02x}}", ch);
        }
    }
    return 0;
}

Bu size {{NN}}, NNkarakterin onaltılık kodunun nerede olduğunu verecektir . Basitçe ayarlayabilirsiniz.printf çıktı tarzı için .

Bu programı burada çalışırken görebilirsiniz, burada:

pax$ printf 'Hello,\tBob\nGoodbye, Bob\n' | ./filterProg
Hello,{{09}}Bob
Goodbye, Bob

Bu yöntem tüm ikili karakterleri aynı "." sembolü. Onları okunabilir sembollerle eşleştiren başka bir yöntem var mı?
Daniel YC Lin

Elbette, bir güncellemede sağladığım farklı bir filtre programıyla çalıştırabilirsiniz.
paxdiablo

1
Daha tr '[:cntrl:] '.'iyi olduğunu düşünüyorum . Ve \000-\010\013\014\016-\037\177-\377'tr sözdiziminizde olmalıdır.
Daniel YC Lin

2
Test ettikten sonra tr '[\000-\010\013\014\016-\037\177-\377]' '_'uygulanabilir, cntrl benim durumum için uygun değil.
Daniel YC Lin

2
Adımın tersi yerine içine biye catyaparak kaydedebilirsiniz . Bu aynı zamanda birden çok dosyayı grep etmenize ve dosya adı referansını çıktıda tutmanıza olanak tanır. grep --texttr
aaaantoine

33

Örneğin, ikili bir dosyadan dizeleri çıkarmak için "dizeleri" kullanabilirsiniz.

strings binary.file | grep foo

Kaynak, her satırda UID ile bir hata ayıklama günlüğü olduğu için benim için iyi çalıştı. Teşekkürler.
mbrownnyc

benim için de iyi çalıştı. Cevabınız için teşekkürler.
Shekhar

2
@Paxdiablo'nun cevabını takdir ediyorum ama hızlı bir cevap için ve işe devam etmek için bunu hata edemezsiniz.
Wil

Paxdiablo çözümünü kullanmaya çalıştım, ancak beklediğim sonuçların hiçbirini bana vermedi. @moodywoody çözümünüz hızlı, basit ve tam olarak ihtiyacım olanı veriyor!
justinhartman

20

Grep'i ikili dosyalara şu şekilde bakmaya zorlayabilirsiniz:

grep --binary-files=text

Ayrıca -o( --only-matching) eklemek isteyebilirsiniz, böylece terminalinizi yıkacak tonlarca ikili anlamsız kelime almazsınız.


çıktı bir uçbirimse ve uçbirim sürücüsü bazılarını komut olarak yorumluyorsa kötü yan etkilere neden olabilecek ikili çöp çıktı verebilir.
Daniel YC Lin

Eğer kullanırsanız --only-matching, ve düzenli ifade keyfi ikili veri uymuyor, bir sorun olmaz.
AB

Normal ifade "birinci. * son" ise ve ikili veriler ". *" kalıbını içeriyorsa, işlem sonrası işlemim için işlemi düzeltemez. Her neyse, teşekkürler.
Daniel YC Lin

16

Grep 2.21'den başlayarak, ikili dosyalar farklı şekilde ele alınır :

İkili verileri ararken, grep artık metin olmayan baytları satır sonlandırıcılar olarak ele alabilir. Bu, performansı önemli ölçüde artırabilir.

Şimdi olan şey, ikili verilerde metin olmayan tüm baytlar (satırsonları dahil) satır sonlandırıcılar olarak ele alınır. Bu davranışı değiştirmek istiyorsanız şunları yapabilirsiniz:

  • kullanın --text. Bu, yalnızca yeni satırların satır sonlandırıcı olmasını sağlayacaktır

  • kullanın --null-data. Bu, yalnızca boş baytların satır sonlandırıcı olmasını sağlayacaktır.


5

grep -a, grep'i grep'in ikili olduğunu düşündüğü bir dosyadan aramaya ve çıktı almaya zorlar. grep - yeniden test.log



2

yapabilirsin

strings test.log | grep -i

bu, çıktıyı okunabilir bir dizge olarak grep'e dönüştürür.


0

Word Extractor aracını da deneyebilirsiniz . Word Extractor, insan metni / sözcükleri içeren dizeleri ikili koddan (exe uygulamaları, DLL'ler) ayırmak için bilgisayarınızdaki herhangi bir dosyayla birlikte kullanılabilir.


Benim durumum, kelime çıkarıcıya ihtiyacım yok, satır numarasını tutmam gerekiyor.
Daniel YC Lin 13

0

Burada "dizeler" komutunun yüklü olmadığı bir sistemde kullandım

cat yourfilename | tr -cd "[:print:]"

Bu, metni yazdırır ve istenmeyen şeylerin kaldırılması için bazı son işlemler gerektiren "cat -v dosya adı" nın aksine, yazdırılamayan karakterleri bir hamlede kaldırır. Bazı ikili verilerin yazdırılabilir olabileceğini unutmayın, bu nedenle iyi şeyler arasında hala anlamsız şeyler alacaksınız. Eğer kullanabilirsen dizelerin bu anlamsız sözleri de ortadan kaldıracağını düşünüyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.