मैं बड़ी फ़ाइलों के साथ एक अजीब मुद्दा है और bash। यह संदर्भ है:
- मेरे पास एक बड़ी फ़ाइल है: 75G और 400,000,000+ लाइनें (यह एक लॉग फ़ाइल है, मेरी खराब है, मैंने इसे बढ़ने दिया)।
- प्रत्येक पंक्ति के पहले 10 चार्ट YYYY-MM-DD प्रारूप में एक समय टिकट है।
- मैं उस फ़ाइल को विभाजित करना चाहता हूं: प्रति दिन एक फ़ाइल।
मैंने निम्नलिखित स्क्रिप्ट के साथ प्रयास किया जो काम नहीं किया। मेरा प्रश्न इस स्क्रिप्ट के काम नहीं करने के बारे में है, न कि वैकल्पिक समाधानों के बारे में ।
while read line; do
new_file=${line:0:10}_file.log
echo "$line" >> $new_file
done < file.log
डिबगिंग के बाद, मुझे new_fileचर में समस्या मिली । यह स्क्रिप्ट:
while read line; do
new_file=${line:0:10}_file.log
echo $new_file
done < file.log | uniq -c
परिणाम देता है bellow (मैं xडेटा को गोपनीय रखने के लिए शेष डालता हूं , अन्य चार्ट वास्तविक हैं)। नोटिस dhऔर छोटे तार:
...
27402 2011-xx-x4
27262 2011-xx-x5
22514 2011-xx-x6
17908 2011-xx-x7
...
3227382 2011-xx-x9
4474604 2011-xx-x0
1557680 2011-xx-x1
1 2011-xx-x2
3 2011-xx-x1
...
12 2011-xx-x1
1 2011-xx-dh
1 2011-xx-x1
1 208--
1 2011-xx-x1
1 2011-xx-dh
1 2011-xx-x1
...
यह मेरी फ़ाइल के प्रारूप में कोई समस्या नहीं है । स्क्रिप्ट cut -c 1-10 file.log | uniq -cकेवल मान्य समय टिकट देती है। दिलचस्प है, उपरोक्त आउटपुट का एक हिस्सा इसके साथ बन जाता है cut ... | uniq -c:
3227382 2011-xx-x9
4474604 2011-xx-x0
5722027 2011-xx-x1
हम देख सकते हैं कि यूनीक गणना के बाद 4474604, मेरी प्रारंभिक स्क्रिप्ट विफल रही।
क्या मैंने बैश में एक सीमा को मारा था जो मुझे नहीं पता है, क्या मुझे बैश में एक बग मिला (यह संभावना नहीं है), या क्या मैंने कुछ गलत किया है?
अपडेट :
समस्या फ़ाइल के 2G पढ़ने के बाद होती है। यह सीम readऔर पुनर्निर्देशन 2 जी से बड़ी फ़ाइलों को पसंद नहीं करता है। लेकिन फिर भी एक अधिक सटीक स्पष्टीकरण के लिए खोज की जा रही है।
अपडेट 2 :
यह निश्चित रूप से बग की तरह दिखता है। इसके साथ पुन: पेश किया जा सकता है:
yes "0123456789abcdefghijklmnopqrs" | head -n 100000000 > file
while read line; do file=${line:0:10}; echo $file; done < file | uniq -c
लेकिन यह वर्कअराउंड के रूप में ठीक काम करता है (यह मुझे लगता है कि इसका एक उपयोगी उपयोग पाया गया cat):
cat file | while read line; do file=${line:0:10}; echo $file; done | uniq -c
जीएनयू और डेबियन के लिए एक बग दायर किया गया है। प्रभावित संस्करण bashडेबियन स्क्वीज़ 6.0.2 और 6.0.4 पर 4.1.5 हैं ।
echo ${BASH_VERSINFO[@]}
4 1 5 1 release x86_64-pc-linux-gnu
Update3:
एंड्रियास श्वाब के लिए धन्यवाद जिन्होंने मेरी बग रिपोर्ट पर तुरंत प्रतिक्रिया दी, यह वह पैच है जो इस दुर्व्यवहार का समाधान है। प्रभावित फाइल lib/sh/zread.cजितनी जल्दी गिल्स ने बताई है:
diff --git a/lib/sh/zread.c b/lib/sh/zread.c index 0fd1199..3731a41 100644
--- a/lib/sh/zread.c
+++ b/lib/sh/zread.c @@ -161,7 +161,7 @@ zsyncfd (fd)
int fd; { off_t off;
- int r;
+ off_t r;
off = lused - lind; r = 0;
rचर का वापसी मान धारण करने के लिए प्रयोग किया जाता है lseek। जैसा lseekकि फ़ाइल की शुरुआत से ऑफसेट लौटाता है, जब यह 2GB से अधिक है, तो intमान नकारात्मक है, जो परीक्षण if (r >= 0)को विफल करने का कारण बनता है जहां इसे सफल होना चाहिए।
readबैश में बयान की एक सीमा की दिशा में इंगित करता है ।