বড় ফাইল এবং এর সাথে আমার একটি অদ্ভুত সমস্যা রয়েছে bash। এটি প্রসঙ্গে:
- আমার কাছে একটি বড় ফাইল রয়েছে: 75 জি এবং 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
ফলাফলটি নমুনা দেয় (আমি 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আমার প্রাথমিক স্ক্রিপ্টটি ব্যর্থ হয়েছে।
আমি কি জানি না এমন ব্যাশে এমন একটি সীমাবদ্ধতা ফেলেছিলাম যা আমি জানি না, আমি কি ব্যাশে কোনও বাগ পেয়েছি (এটি অসম্ভব সম্ভাবনাময়), বা আমি কোনও ভুল করেছি?
আপডেট :
ফাইলটির 2 জি পড়ার পরে সমস্যাটি ঘটে। এটি seams readএবং পুনঃনির্দেশ 2G এর চেয়ে বড় ফাইল পছন্দ করে না। তবে এখনও আরও সুনির্দিষ্ট ব্যাখ্যা অনুসন্ধান করা হচ্ছে।
আপডেট 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 .4
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বিবৃতিতে সীমাবদ্ধতার দিক নির্দেশ করতে seams করে ।