क्या यह मुमकिन है, एक मध्यस्थ बाइट काउंट ऑफ़सेट से फ़ाइल पढ़ना शुरू करने के लिए?


22

मैं एक तारीख का पता लगाना चाहता हूं जो 8 जीबी लॉग (पाठ) में कहीं है।

क्या मैं पूर्ण अनुक्रमिक रीड को कुछ हद तक बायपास कर सकता हूं, और पहले फ़ाइल के बाइनरी विभाजन (आकार), या किसी तरह से फाइलसिस्टम को नेविगेट करना inodes(जो मुझे बहुत कम पता है ), प्रत्येक विभाजन बिंदु से पढ़ना शुरू करने के लिए, जब तक मुझे एक उपयुक्त ऑफसेट नहीं मिल जाता है डेट को कोट करने वाली लाइन के लिए अपना टेक्स्ट खोज कहां से शुरू करें?

tailअंतिम पंक्ति का वाचन सामान्य अनुक्रमिक रीड का उपयोग नहीं करता है, इसलिए मुझे आश्चर्य है कि अगर यह सुविधा किसी तरह से उपलब्ध है, या क्या मुझे पायथन या सी / सी ++ का उपयोग करने की आवश्यकता होगी ... लेकिन मुझे विशेष रूप से एक bashविकल्प में दिलचस्पी है ..


जवाबों:


8
for (( block = 0; block < 16; block += 1 ))
do 
    echo $block; 
    dd if=INPUTFILE skip=$((block*512))MB bs=64 count=1 status=noxfer 2> /dev/null | \
        head -n 1
done

जो .. कोई टेम्प-स्प्लिट फ़ाइलें नहीं बनाता है, प्रत्येक रन पर * 512MB डेटा ब्लॉक करता है, उस स्थिति से 64 बाइट्स पढ़ता है और आउटपुट को उस 64 बाइट्स की पहली पंक्ति तक सीमित करता है।

आप जो कुछ भी आपको लगता है कि आप की जरूरत है 64 को समायोजित करना चाहते हो सकता है।


@akira .. यह वास्तव में अच्छा लग रहा है, लेकिन मैं इसे पहले थोड़ा और अधिक देखना चाहता हूं .. (इसलिए, कल तक .....
पीटर।

1
@akira .. 'dd' एकसाथ है। यह बाइनरी स्प्लिट खोज के साथ अच्छी तरह से काम करता है ... मैं अब 1 सेकंड के अंदर एक 8G फ़ाइल से सॉर्ट की गई लाइन (इसकी तिथि कुंजी द्वारा) निकाल सकता हूं ... तो ऐसा लगता है कि मैं अपना 3 प्राप्त कर लूंगा दो कुंजी (समावेशी) के बीच की तारीखों को निकालने के लिए दूसरा व्यक्तिगत लक्ष्य .. आउटपुट समय को छोड़कर, जो इस बात पर निर्भर करता है कि कितना आउटपुट हो रहा है .. मैं इसके ddलिए भी उपयोग करूँगा ... यह एक महान उपकरण है! :)
पीटर

30

ऐसा लगता है कि आप चाहते हैं:

tail -c +1048576

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

tail -c +1M

कट के बाद बाइट्स की एक निश्चित संख्या प्राप्त करने के लिए, बाकी सभी फ़ाइल के बजाय, बस इसे सिर के माध्यम से पाइप करें:

tail -c +1048576 | head -c 1024

Linux / bash लचीलापन awsome है (मैंने निश्चित रूप से Linux पर स्विच करने में बहुत लंबा समय बिताया है)। मैंने अभी तक अकीरा के उत्तर को स्वीकार कर लिया था, लेकिन मैंने इसे तब तक खींचा है जब तक कि मैं इसका पूरी तरह से आकलन नहीं करता। ddएक विशिष्ट बाइट के लिए कूदता है (जैसा कि होता है tail), लेकिन यह अज्ञात लाइन की लंबाई के आसपास एक कोडिंग दर्द है, और फिर प्रमुख आंशिक रेखाओं से पट्टी करने के लिए एक कॉल करने के लिए ... यह पूंछ की तरह दिखता है। सिर दर्द रहित (जितनी तेजी से?) कर सकता है । मुझे समझ नहीं आ रहा है कि सिर को पूंछ पर टैप बंद कैसे किया जा सकता है, लेकिन ऐसा लगता है :) यह एक मामला होना चाहिए: यदि सिर प्राप्त करना बंद हो जाता है, तो पूंछ भेजना बंद कर देता है (और आगे पढ़ना बंद कर देता है)। जाना चाहिए .. कल वापस।
पीटर.ओ.

@ fred.bear: tail/ के headरूप में अच्छी तरह से लाइन-लंबाई अनुमान लगाने में सक्षम नहीं हैं। आपको स्थिति x पर कूदना होगा और फिर आप अगले के लिए x के बाएँ या दाएँ देख सकते हैं \n। इससे कोई फर्क नहीं पड़ता कि कार्यक्रम को क्या कहा जाता है। इसलिए, दोनों स्थितियों में आप x पर जाते हैं और फिर headपंक्ति के अगले छोर के दाईं ओर देखने के लिए उपयोग करते हैं।
अकीरा

tail|headकी गिनती = वैल के बारे में बिल्कुल भी चिंतित नहीं होने की क्षमता प्रदान करता है dd। 'Dd' के साथ, यदि मैं पर्याप्त डेटा नहीं हड़पता, तो यह "गेम ओवर" है। मध्यस्थ रेखा की लंबाई का लचीलापन बहुत अच्छा है। मैंने 'dd' के लिए एक फंक्शन लिखा है, जो "अगली नज़दीकी" पूरी लाइन और इसकी भरपाई देता है, लेकिन मैं लंबाई के मुद्दे से बचना पसंद करूँगा। मैंने अब पूंछ परीक्षण किया है। सिर, और यह शुरू में (100MB तक ऑफसेट करने के लिए) अच्छा प्रदर्शन करता है, लेकिन ऑफसेट = 8GB पर एक एक्सेस के लिए 2 मिनट लेने के लिए नाटकीय रूप से धीमा हो जाता है (मैं awkइसे 1 मिनट में कर सकता हूं ) ... तो यह बहुत अच्छा है के लिए छोटे फ़ाइल है .. मुझे पूंछ / सिर कॉम्बो की :) बारे में पता करने के लिए धन्यवाद
Peter.O

2

मैं कुछ इस तरह से लॉग इन करने के लिए 512MiB विखंडू जल्दी पार्सिंग में विभाजित करने की कोशिश करूँगा।

split <filename> -b 536870912

यदि आप फ़ाइल की तलाश कर रहे हैं तो निम्नलिखित काम करेगा:

for file in x* ; do
  echo $file
  head -n 1 $file
done

अपनी तिथि के लिए किस फ़ाइल को grep निर्धारित करने के लिए उस आउटपुट का उपयोग करें।


धन्यवाद, लेकिन यह एक क्रमिक खोज की तुलना में धीमी है। मेरी टिप्पणियों पर एक नज़र डालिए यहाँ unix.stackexchange.com/questions/8121/… (बजाय एक ही चीज़ यहाँ फिर से लिखने के लिए)
Peter.O

'स्प्लिट' का उपयोग करके आप हर एक बाइट को एक बार छूते हैं। यदि आप ऐसा करते हैं, तो आप पूरे 8gb को भी प्राप्त कर सकते हैं।
अकीरा

@sifusam .. मैं एक बाइनरी स्प्लिट सर्च करना चाहता हूं (न कि सिर्फ फाइलों को विभाजित करना) en.wikipedia.org/wiki/Binary_search_algorithm ... तो यह एक डिफरेंट सवाल के लिए एक अच्छा जवाब था :) .. जवाब देने के लिए धन्यवाद .. +1 करने के लिए आपको रोलिंग मिलेगी ....
पीटर।

0

यहां मेरी स्क्रिप्ट है, मैं पहली पंक्ति की तलाश कर रहा हूं, पहला क्षेत्र मेरी संख्या से मेल खा रहा है। लाइनों को पहले क्षेत्र के अनुसार क्रमबद्ध किया जाता है। मैं 128K के ब्लॉकों की पहली पंक्ति की जांच करने के लिए dd का उपयोग करता हूं, फिर मैं ब्लॉक में कूदता हूं और एक खोज करता हूं। यह दक्षता में सुधार है फ़ाइल 1M से अधिक है।

किसी भी टिप्पणी या सुधार की सराहना की है!

#!/bin/bash

search=$1;
f=$2;

bs=128;

max=$( echo $(du $f | cut -f1)" / $bs" | bc );
block=$max;
for i in $(seq 0 $max); do
 n=$(dd bs=${bs}K skip=$i if=$f 2> /dev/null| head -2 | tail -1 | cut -f1)
 if [ $n -gt $search ]; then
  block=`expr $i - 1` 
  break;
 fi
done; 
dd bs=${bs}K skip=$block if=$f 2> /dev/null| tail -n +2 | awk -v search="$search" '$1==search{print;exit 1;};$1>search{exit 1;};';

* संपादित करें * ** ग्रेप बहुत तेजी से और है पावती भी बेहतर

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