एक फ़ाइल को विभाजित करना: `sed` में` egrep` को प्रतिस्थापित करें


0

मैं अपनी $ फ़ाइल को एक्स लाइनों में आधे हिस्से में विभाजित करना चाहता हूं , और यह जांचें कि लॉग में कितनी लाइनें " मृत " हैं। मैंने निम्नलिखित के साथ शुरुआत की:

half=`expr $(egrep -c . $file) / 2`

sed -n 1,${half}p $file | 
    xargs echo $file $half $(egrep -c dead $I) > log_1
sed -n ${half},${egrep -c . $file}p | 
    xargs echo $file $half $(egrep -c dead $I) > log_2

पहले sedकमांड के लिए आउटपुट ठीक है, लेकिन जब egrepइसकी सीमा में प्रतिस्थापन sedगलत हो जाता है:

DeadOrAlive 5 2
-bash: ${half},${egrep -c . $file}p: bad substitution

क्या फ़ाइल को विभाजित करने का एक अधिक कुशल तरीका है bash?


$(...)और ${...}अलग-अलग निर्माण हैं। पूर्व कमांड प्रतिस्थापन है, बाद वाला पैरामीटर विस्तार है।
चोराबा

आपकी पहली egrepगैर-रिक्त रेखाएं गिनाती हैं। grep -c ^ fileखाली लाइनों सहित कुल लाइन गणना का उत्पादन करेगा। (यदि आपकी फ़ाइल में कोई खाली लाइनें नहीं हैं, तो निश्चित रूप से दोनों समान हैं।) wc -l <fileसंभवतः तेज़ है क्योंकि इसे किसी भी regex मिलान की आवश्यकता नहीं है। यदि आप विशेष रूप से गैर-खाली लाइनों की गिनती करना चाहते हैं, तो निश्चित रूप से आपको मैचों की जांच करनी होगी।
त्रिपली

क्या आप $Iशामिल होने की उम्मीद करते हैं?
त्रिपली

sed "$half,\$"$halfफ़ाइल के अंत से लाइनों का चयन करेंगे , हालांकि आपके कोड $halfमें पहली और दूसरी छमाही दोनों में सबसे मध्य फ़ाइल (लाइन नंबर ) शामिल होगी ।
ट्रिपलए

sed "1,${half}d" fileपहली $halfपंक्तियों को हटा देगा , और बाकी प्रिंट कर देगा। इसके साथ, आप फ़ाइल को दो गैर-अतिव्यापी विभाजन में ठीक से विभाजित कर सकते हैं।
त्रिपली

जवाबों:


0
  1. उपयोग करना wc, headऔर tail:

    half=$(( $(wc -l "$file")/2 ))
    head -$half | egrep -c dead | xargs echo "$file" $half > log_1
    tail -$half | egrep -c dead | xargs echo "$file" $half > log_2
  2. का उपयोग कर split:

    split -a1 --numeric-suffixes=1 -n 'l/2' "$file" "$file"_
    echo "$file" "$file"_1 $(egrep -c dead "$file_1") > log_1
    echo "$file" "$file"_2 $(egrep -c dead "$file"_2) > log_2
    rm "$file"_[12]

0

यहाँ एक Awk समाधान है।

awk '/dead/ { a[++n] = NR }
    END { for (i=1; i<=n; i++) if (a[i] > NR/2) break
        print ARGV, int(NR/2), i-1 >"log_1";
        print ARGV, int(NR/2)+(int(NR/2)!=NR/2), n-i+1 >"log_2" }' file

हम सरणी aमें माचिस की संख्या को एकत्रित करते हैं । फिर हम यह पता लगाते हैं कि सरणी में पंक्ति संख्याएँ मध्य रेखा से कितनी छोटी हैं; उनकी गिनती पहले विभाजन को सौंपी जाती है। (हमें तब उपयोग करना होगा i-1क्योंकि जब हम breakलूप से बाहर होते हैं तो हम पहले से ही विभाजन बिंदु से पहले होते हैं ।)

सामान्य तौर पर, आप एक ही फाइल को कई बार रीएयर करने से बचना चाहते हैं, खासकर अगर यह बड़ी हो सकती है; और दूसरी बात, प्रक्रियाओं की संख्या को कम करने का प्रयास करें।

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


कड़ाई से बोलते हुए, हमें close()उन फ़ाइलों को खोलना चाहिए जिन्हें हम खोलते हैं, लेकिन जब तक केवल दो हैं, मैंने परेशान नहीं किया।
त्रिवेणी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.