पाठ फ़ाइल को कैसे प्राप्त करें जिसमें कुछ बाइनरी डेटा शामिल हैं?


122

जीआरपी रिटर्न

बाइनरी फ़ाइल टेस्ट.लॉग मैच

उदाहरण के लिए

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

काश परिणाम लाइन 1 और लाइन 3 (कुल दो लाइनें) दिखाएगा।

क्या trजीआरपी को फिर से काम करने देने के लिए अप्राप्य डेटा को पठनीय डेटा में परिवर्तित करना संभव है ?


कृपया ध्यान दें कि एक प्रोग्राम है जो बाइनरी फ़ाइल से बाइनरी वर्णों को फ़िल्टर करता है और केवल पाठ वर्ण (पठनीय) रखता है। यहाँ: soft.tahionic.com/download-words_extractor/index.html
InTheNameOfScience

क्षमा करें, लेकिन ... क्या आप कमांड -eमें गायब नहीं हैं echo?
सोपालाजो डे एरिएरेज़

यदि आप 'zsh' का उपयोग करते हैं, तो यह बिना -e के ठीक है। यदि आप 'बैश' का उपयोग करते हैं, तो आपको '-ई' जोड़ना चाहिए।
डैनियल वाईसी लिन

जवाबों:


67

आप cat -vउदाहरण के माध्यम से डेटा फ़ाइल चला सकते हैं

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

जो तब कबाड़ को हटाने के लिए आगे की प्रक्रिया के बाद हो सकता है; यह trकार्य के लिए उपयोग करने के बारे में आपकी क्वेरी के लिए सबसे अधिक अनुरूप है ।


5
मेरी समस्या का समाधान किया। धन्यवाद! यहाँ क्या man catहै के बारे में कहते हैं -v:-v, --show-nonprinting use ^ and M- notation, except for LFD and TAB
tommy.carstensen

ध्यान दें कि यह एक पाइपलाइन में भी काम करता है। जैसेset | cat -v | grep variable
२०:१६

1
अगर grep --text काम करता है तो इसका उपयोग क्यों करें? यह बहुत अधिक जटिल लगता है।
माइकल हैफेल

grep --textहमेशा काम नहीं करता है; यह एक फ़ाइल टर्मिनेटर के रूप में CTRL + D का सम्मान करता है। तो अगर आपके पास अपनी बाइनरी फ़ाइल में है, तो जीआरपी जल्दी बाहर निकल जाएगा।
टॉमी

110
grep -a

यह उससे आसान नहीं हो सकता।


3
यह वही है grep --textजो 2 साल पहले paxdiablo ने उल्लेख किया है
user829755

4
हाँ, सिवाय इसके कि यह OSX पर तब तक काम नहीं करेगा जब तक आप निम्नलिखित कार्य नहीं करते:LC_ALL="C" grep -a
क्रिस स्ट्रैटन

91

एक तरीका यह है कि द्विआधारी फ़ाइलों को केवल पाठ के रूप में माना जाए, grep --textलेकिन इससे बाइनरी जानकारी आपके टर्मिनल पर भेजी जा सकती है। यह वास्तव में एक अच्छा विचार नहीं है यदि आप एक टर्मिनल चला रहे हैं जो आउटपुट स्ट्रीम (जैसे VT / DEC या कई अन्य) की व्याख्या करता है।

वैकल्पिक रूप से, आप trनिम्नलिखित कमांड के माध्यम से अपनी फ़ाइल भेज सकते हैं :

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

यह एक अंतरिक्ष चरित्र (न्यूलाइन को छोड़कर) और 126 से अधिक कुछ भी को एक .चरित्र में बदल देगा, केवल एक चरित्र में, केवल प्रिंटबल्स को छोड़कर।


यदि आप चाहते हैं कि हर "अवैध" चरित्र को एक अलग से बदल दिया जाए, तो आप निम्नलिखित सी प्रोग्राम की तरह कुछ का उपयोग कर सकते हैं, एक क्लासिक मानक इनपुट फ़िल्टर:

#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;
}

यह आपको देगा {{NN}}, NNचरित्र के लिए हेक्स कोड कहां है। आप बस printfआउटपुट की जो भी शैली चाहते हैं उसके लिए समायोजित कर सकते हैं।

आप उस कार्यक्रम को यहां कार्रवाई में देख सकते हैं, जहां यह है:

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

यह विधि सभी बाइनरी चार को समान में मैप कर रही है। ' प्रतीक। वहाँ अन्य विधि उन्हें पठनीय प्रतीकों के लिए मैपिंग है?
डैनियल YC लिन

ज़रूर, आप इसे एक अलग फ़िल्टर प्रोग्राम के माध्यम से चला सकते हैं, जिनमें से एक मैंने अपडेट में प्रदान किया है।
paxdiablo

1
मुझे लगता tr '[:cntrl:] '.'है कि बेहतर है। और यह \000-\010\013\014\016-\037\177-\377'आपके tr सिंटैक्स में होना चाहिए ।
डैनियल YC लिन

2
परीक्षण करने के बाद, tr '[\000-\010\013\014\016-\037\177-\377]' '_'व्यावहारिक, मेरे मामले के लिए उपयुक्त नहीं है।
डैनियल YC लिन

2
आप को बचा सकता है catपाइपिंग द्वारा कदम grep --textमें trठीक इसके विपरीत के बजाय। इससे आप कई फ़ाइलों को प्राप्त कर सकते हैं और आउटपुट में फ़ाइल का नाम संदर्भ रख सकते हैं।
आहातोइनिन

33

उदाहरण के लिए, बाइनरी फ़ाइल से स्ट्रिंग्स निकालने के लिए आप "स्ट्रिंग्स" का उपयोग कर सकते हैं

strings binary.file | grep foo

मेरे लिए अच्छी तरह से काम किया क्योंकि स्रोत प्रत्येक पंक्ति पर यूआईडी के साथ डिबग लॉग था। धन्यवाद।
mbrownnyc

मेरे लिए भी अच्छा काम किया। आपके उत्तर के लिए धन्यवाद। मेरा दिन बचा लिया :)
शेखर

2
मैं @paxdiablo के उत्तर की सराहना करता हूं, लेकिन एक त्वरित उत्तर के लिए और नौकरी के साथ आप इस पर गलती नहीं कर सकते।
विल् अप।

हालांकि paxdiablo समाधान का उपयोग करने की कोशिश की, लेकिन इससे मुझे कोई भी परिणाम नहीं मिला जिसकी मुझे उम्मीद थी। @ moodywoody आपका समाधान त्वरित, सरल है और बिल्कुल वही है जो मुझे चाहिए था!
जस्टिननमैन

20

आप grep को बाइनरी फ़ाइलों के साथ देखने के लिए बाध्य कर सकते हैं:

grep --binary-files=text

आप जोड़ना भी चाहते हैं -o( --only-matching) तो आपको बाइनरी गिब्रिश के टन नहीं मिलेंगे जो आपके टर्मिनल को बोर करेंगे।


बाइनरी कचरा का उत्पादन कर सकता है, जिसका बुरा साइड इफेक्ट हो सकता है अगर आउटपुट एक टर्मिनल है और अगर टर्मिनल ड्राइवर इसमें से कुछ को कमांड के रूप में व्याख्या करता है।
डैनियल YC लिन

यदि आप उपयोग करते हैं --only-matching, और आपका regex मनमाने ढंग से बाइनरी डेटा से मेल नहीं खाता है, तो आपको कोई समस्या नहीं होगी।
एबी

यदि नियमित अभिव्यक्ति 'पहले। * अंत' है और बाइनरी डेटा में '*।' पैटर्न है, तो यह मेरी पोस्ट प्रोसेसिंग के लिए सही प्रक्रिया नहीं कर सकता है। कोई बात नहीं धन्यवाद।
डैनियल YC लिन

16

ग्रेप 2.21 के साथ शुरू, बाइनरी फ़ाइलों को अलग तरीके से व्यवहार किया जाता है :

बाइनरी डेटा की खोज करते समय, grep अब गैर-टेक्स्ट बाइट्स को लाइन टर्मिनेटर के रूप में मान सकता है। यह प्रदर्शन को काफी बढ़ा सकता है।

तो अब क्या होता है बाइनरी डेटा के साथ, सभी गैर-पाठ बाइट्स (न्यूलाइन सहित) को लाइन टर्मिनेटर के रूप में माना जाता है। यदि आप इस व्यवहार को बदलना चाहते हैं, तो आप कर सकते हैं:

  • उपयोग करें --text। यह सुनिश्चित करेगा कि केवल नई लाइनें लाइन टर्मिनेटर हैं

  • उपयोग करें --null-data। यह सुनिश्चित करेगा कि केवल नल बाइट्स लाइन टर्मिनेटर हैं


5

grep -a, grep को ऐसी फ़ाइल से खोज और आउटपुट के लिए बाध्य करेगा जो grep को लगता है कि द्विआधारी है। grep -a re test.log


3

जैसा कि जेम्स सेल्वाकुमार ने पहले ही कहा था, grep -aचाल है। -a या --text पाठ के रूप में इनपुटस्ट्रीम को संभालने के लिए Grep को बाध्य करता है। मैनपेज http://unixhelp.ed.ac.uk/CGI/man-cgi?grep देखें

प्रयत्न

cat test.log | grep -a somestring

2

तुम कर सकते हो

strings test.log | grep -i

यह आउटपुट को ग्रेप के लिए पठनीय स्ट्रिंग के रूप में परिवर्तित करेगा।


0

आप Word Extractor टूल भी आज़मा सकते हैं । बाइनरी कोड (exe एप्लिकेशन, DLL) से मानव पाठ / शब्द वाले स्ट्रिंग्स को अलग करने के लिए आपके कंप्यूटर में किसी भी फाइल के साथ वर्ड एक्सट्रैक्टर का उपयोग किया जा सकता है।


मुझे मेरा मामला है, मुझे शब्द निकालने की आवश्यकता नहीं है, मुझे लाइन नंबर रखने की आवश्यकता है।
डैनियल YC लिन

0

यहां मैंने एक ऐसी प्रणाली का उपयोग किया है जिसमें "स्ट्रिंग्स" कमांड स्थापित नहीं है

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

यह पाठ को प्रिंट करता है और "कैट -v फाइलनेम" के विपरीत एक गिर गए झूठा अक्षर को हटा देता है, जिससे अवांछित सामान को हटाने के लिए कुछ पोस्टप्रोसेसिंग की आवश्यकता होती है। ध्यान दें कि कुछ द्विआधारी डेटा प्रिंट करने योग्य हो सकते हैं, इसलिए आपको अभी भी अच्छे सामान के बीच कुछ अस्पष्ट मिलेगा। मुझे लगता है कि स्ट्रिंग्स इस जिबरिश को भी हटा देती है, अगर आप इसका इस्तेमाल कर सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.