बाइनरी फ़ाइल में बाइट की घटना के आंकड़े कैसे इकट्ठा करें?


13

मैं इसके बराबर जानना चाहता हूँ

cat inputfile | sed 's/\(.\)/\1\n/g' | sort | uniq -c

प्रस्तुत है /programming/4174113/how-to-gather-characters-usage-statistics-in-text-file-use-unix-commands में बाइनरी फ़ाइलों की गिनती के लिए पाठ फ़ाइलों में चरित्र उपयोग के आँकड़ों के उत्पादन के लिए गिनती। अक्षरों के बजाय साधारण बाइट्स, यानी आउटपुट के रूप में होना चाहिए

18383 57
12543 44
11555 127
 8393 0

यदि कमांड वर्णों के लिए संदर्भित के रूप में लंबे समय तक लेती है, तो इससे कोई फर्क नहीं पड़ता।

यदि मैं वर्णों के लिए कमांड को बाइनरी फाइलों पर लागू करता हूं, तो आउटपुट में अनपेक्षित वर्णों के लंबे समय के अनुक्रम के लिए आँकड़े हैं (मैं उस बारे में स्पष्टीकरण नहीं मांगता)।

जवाबों:


8

GNU के साथ od:

od -vtu1 -An -w1 my.file | sort -n | uniq -c

या इसके साथ अधिक कुशलता से perl(बाइट्स के लिए एक गिनती (0) भी उत्पन्न होती है)

perl -ne 'BEGIN{$/ = \4096};
          $c[$_]++ for unpack("C*");
          END{for ($i=0;$i<256;$i++) {
              printf "%3d: %d\n", $i, $c[$i]}}' my.file

पहली पंक्ति में संख्याओं को सही तरीके से पहचानने के लिए मुझे क्रमशः जोड़ना | sort -nऔर | sort -n -rअवरोही क्रम के लिए (छँटाई करना सवाल का हिस्सा नहीं था)। छँटाई बेहतर किया जा सकता है ...
कार्ल रिक्टर

पूरी फ़ाइल को सॉर्ट करने के लिए थोड़ा ओवरकिल लगता है, लेकिन मेरे लिए ठीक काम किया।
माइकल एंडरसन

अच्छा बिंदु @ कर्ल, हालांकि अनुरोध नहीं किया गया है, sort -nयहां उपयोग करने से बहुत अधिक समझ में आता है। उत्तर अपडेट किया गया।
स्टीफन चेज़लस

5

सॉर्ट का उपयोग करने वाली बड़ी फ़ाइलों के लिए धीमी गति से होगा। मैंने समतुल्य समस्या को हल करने के लिए एक छोटा सी कार्यक्रम लिखा था ( परीक्षण के साथ मेकफाइल के लिए इस जिस्ट को देखें ):

#include <stdio.h>

#define BUFFERLEN 4096

int main(){
    // This program reads standard input and calculate frequencies of different
    // bytes and present the frequences for each byte value upon exit.
    //
    // Example:
    //
    //     $ echo "Hello world" | ./a.out
    //
    // Copyright (c) 2015 Björn Dahlgren
    // Open source: MIT License

    long long tot = 0; // long long guaranteed to be 64 bits i.e. 16 exabyte
    long long n[256]; // One byte == 8 bits => 256 unique bytes

    const int bufferlen = BUFFERLEN;
    char buffer[BUFFERLEN];
    int i;
    size_t nread;

    for (i=0; i<256; ++i)
        n[i] = 0;

    do {
        nread = fread(buffer, 1, bufferlen, stdin);
        for (i = 0; i < nread; ++i)
            ++n[(unsigned char)buffer[i]];
        tot += nread;
    } while (nread == bufferlen);
    // here you may want to inspect ferror of feof

    for (i=0; i<256; ++i){
        printf("%d ", i);
        printf("%f\n", n[i]/(float)tot);
    }
    return 0;
}

उपयोग:

gcc main.c
cat my.file | ./a.out

क्या आपके पास एक परीक्षण है? कोड में कोई टिप्पणी नहीं है। यह सामान्य रूप से अप्रयुक्त और अप्रमाणित कोड का उपयोग करने के लिए एक अच्छा विचार नहीं है - चाहे वह सामान्य अभ्यास हो या न हो। इस प्लेटफ़ॉर्म पर संशोधनों की समीक्षा करने की संभावना भी सीमित है, एक स्पष्ट कोड होस्टिंग प्लेटफ़ॉर्म पर विचार करें।
कार्ल रिक्टर

@KarlRichter परीक्षण एक अच्छा विचार था। मुझे पुराने संस्करण '' 0 'वर्णों पर आधारित मिले। यह संस्करण काम करना चाहिए (कम से कम कुछ बुनियादी परीक्षण पास करता है)।
बज़र्न डाहलग्रेन ने

fgetsएक लाइन मिलती है, बफर-फुल नहीं। आप स्टड से पढ़ी गई प्रत्येक पंक्ति के लिए 4096-बाइट पूर्ण बफर स्कैन कर रहे हैं। आपको freadयहां जरूरत है, नहीं fgets
स्टीफन चेज़लस

@ स्टीफनचेज़लस महान - को भय का नहीं पता था (शायद ही कभी मैं / सी से ओ)। इसके बजाय फ़्रेड का उपयोग करने के लिए अद्यतन उदाहरण।
बज़र्न डाहलग्रेन ने

मैंने ifप्रिंटफ स्टेटमेंट के चारों ओर एक ब्लॉक जोड़ा है , जो आउटपुट को अधिक पठनीय बनाता है यदि कुछ बाइट इनपुट फ़ाइल में नहीं होते हैं: gist.github.com/martinvonwittich/…
मार्टिन वॉन

3

जैसा कि, सिग्मा और सीवी अक्सर महत्वपूर्ण होते हैं जब द्विआधारी फाइलों की सामग्री के सांख्यिकीय आंकड़ों को देखते हुए, मैंने एक cmdline प्रोग्राम बनाया है जो इस सारे डेटा को सिग्मा से बाइट विचलन के एससीआई सर्कल के रूप में रेखांकन करता है।
http://wp.me/p2FmmK-96
यह आँकड़े निकालने के लिए grep, xargs और अन्य उपकरणों के साथ उपयोग किया जा सकता है। यहाँ छवि विवरण दर्ज करें


1

recodeकार्यक्रम या तो बाइट्स के लिए या विभिन्न वर्ण सेट के पात्रों के लिए आवृत्ति आंकड़े या तो भी बड़ी फ़ाइलों के लिए जल्दी से ऐसा कर सकते हैं,। उदाहरण के लिए बाइट आवृत्तियों की गणना करने के लिए:

$ echo hello there > /tmp/q
$ recode latin1/..count-characters < /tmp/q
1  000A LF   1  0020 SP   3  0065 e    2  0068 h    2  006C l    1  006F o
1  0072 r    1  0074 t

सावधानी - अपनी फ़ाइल को मानक इनपुट के रूप में पुनः दर्ज करने के लिए निर्दिष्ट करें, अन्यथा यह चुपचाप इसे चरित्र आवृत्तियों के साथ बदल देगा!

recode utf-8/..count-characters < fileइनपुट फ़ाइल को utf-8 के रूप में मानने के लिए उपयोग करें । कई अन्य वर्ण सेट उपलब्ध हैं, और यह विफल हो जाएगा यदि फ़ाइल में कोई भी अवैध वर्ण हैं।


1

यह स्टीफन के odजवाब के समान है लेकिन यह बाइट के ASCII मूल्य को दर्शाता है। यह आवृत्ति / आवृत्तियों की संख्या के आधार पर भी छांटा जाता है।

xxd -c1 my.file|cut -c10-|sort|uniq -c|sort -nr

मुझे नहीं लगता कि यह कई प्रक्रियाओं के शुरू होने के बाद से कुशल है, लेकिन यह एकल फ़ाइलों, विशेष रूप से छोटी फ़ाइलों के लिए अच्छा है।

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