আমার কাছে প্রায় 10 মিলিয়ন লাইনযুক্ত একটি ফাইল রয়েছে।
আমি এই ফাইলের সমস্ত লাইন ছয় অক্ষরের চেয়ে কম মুছে ফেলতে চাই।
আমি এটা কিভাবে করবো?
আমার কাছে প্রায় 10 মিলিয়ন লাইনযুক্ত একটি ফাইল রয়েছে।
আমি এই ফাইলের সমস্ত লাইন ছয় অক্ষরের চেয়ে কম মুছে ফেলতে চাই।
আমি এটা কিভাবে করবো?
উত্তর:
এটি করার অনেকগুলি উপায় রয়েছে।
ব্যবহার grep
:
grep -E '^.{6,}$' file.txt >out.txt
এখন out.txt
ছয় বা তার বেশি অক্ষরের লাইন থাকবে।
বিপরীত উপায়:
grep -vE '^.{,5}$' file.txt >out.txt
sed
5 বা তার কম দৈর্ঘ্যের লাইনগুলি ব্যবহার করে :
sed -r '/^.{,5}$/d' file.txt
বিপরীত উপায়, ছয় বা তার বেশি দৈর্ঘ্যের মুদ্রণ লাইন:
sed -nr '/^.{6,}$/p' file.txt
>
অপারেটর ব্যবহার করে আপনি আলাদা ফাইলে আউটপুট সংরক্ষণ করতে পারেন grep
অথবা -i
বিকল্পগুলির বিকল্প ব্যবহার করে স্থানের মধ্যে ফাইলটি সম্পাদনা করতে পারেন sed
:
sed -ri.bak '/^.{6,}$/' file.txt
আসল ফাইলটিকে ব্যাক আপ করা হবে file.txt.bak
এবং পরিবর্তিত ফাইলটি হবে file.txt
।
আপনি যদি ব্যাকআপ রাখতে চান না:
sed -ri '/^.{6,}$/' file.txt
শেল, স্লোয়ার ব্যবহার করে এটি করবেন না , এটি কেবল অন্য পদ্ধতিটি দেখানোর জন্যই:
while IFS= read -r line; do [ "${#line}" -ge 6 ] && echo "$line"; done <file.txt
ব্যবহার python
, এমনকি ধীর চেয়ে grep
, sed
:
#!/usr/bin/env python2
with open('file.txt') as f:
for line in f:
if len(line.rstrip('\n')) >= 6:
print line.rstrip('\n')
আরও পাইথোনিক হওয়ার জন্য আরও ভাল ব্যবহারের তালিকা বোধগম্যতা:
#!/usr/bin/env python2
with open('file.txt') as f:
strip = str.rstrip
print '\n'.join([line for line in f if len(strip(line, '\n')) >= 6]).rstrip('\n')
এটা খুবই সাধারণ:
grep ...... inputfile > resultfile #There are 6 dots
এই অত্যন্ত কার্যকরী, যেমন grep
চেয়ে দরকার আরো বিশ্লেষণ করতে চেষ্টা করবে না, কিংবা অন্য কোন উপায়ে অক্ষর ব্যাখ্যা করা: এটা শুধু stdout- এ একটি (পুরো) লাইন (যা শেল তারপর resultfile রিডাইরেক্ট) পাঠাতে যত তাড়াতাড়ি 6 দেখেছি এই রেখায় .
অক্ষরগুলি ( একটি রেজিপেক্স প্রসঙ্গে কোনও 1 টি অক্ষরের সাথে মেলে)।
সুতরাং গ্রেপ শুধুমাত্র আউটপুট লাইনগুলিতে 6 (বা আরও বেশি) অক্ষর রাখে এবং অন্যগুলি গ্রেপ দ্বারা আউটপুট হয় না যাতে তারা ফলাফলটি ফাইল করে না।
দ্রুততম উপায়: এই সি প্রোগ্রামটি সংকলন এবং চালনা করুন:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_BUFFER_SIZE 1000000
int main(int argc, char *argv[]) {
int length;
if(argc == 3)
length = atoi(argv[2]);
else
return 1;
FILE *file = fopen(argv[1], "r");
if(file != NULL) {
char line[MAX_BUFFER_SIZE];
while(fgets(line, sizeof line, file) != NULL) {
char *pos;
if((pos = strchr(line, '\n')) != NULL)
*pos = '\0';
if(strlen(line) >= length)
printf("%s\n", line);
}
fclose(file);
}
else {
perror(argv[1]);
return 1;
}
return 0;
}
সংকলন করুন, দিয়ে gcc program.c -o program
চালান ./program file line_length
(যেখানে file
= ফাইলের পথে = এবং line_length
ন্যূনতম লাইন দৈর্ঘ্য, আপনার ক্ষেত্রে 6
; সর্বাধিক লাইন দৈর্ঘ্য 1000000
প্রতি লাইন অক্ষরে সীমাবদ্ধ ; আপনি এর মান পরিবর্তন করে এটি পরিবর্তন করতে পারবেন MAX_BUFFER_SIZE
)।
(বিকল্প করার জন্য কৌশল \n
সঙ্গে \0
পাওয়া এখানে ।)
শেল সমাধান ব্যতীত এই প্রশ্নের প্রস্তাবিত অন্যান্য সমস্ত সমাধানের সাথে তুলনা (8 টি অক্ষরের গড় দৈর্ঘ্য 10M লাইন সহ ~ 91MB ফাইলে পরীক্ষা করা):
time ./foo file 6
real 0m1.592s
user 0m0.712s
sys 0m0.160s
time grep ...... file
real 0m1.945s
user 0m0.912s
sys 0m0.176s
time grep -E '^.{6,}$'
real 0m2.178s
user 0m1.124s
sys 0m0.152s
time awk 'length>=6' file
real 0m2.261s
user 0m1.228s
sys 0m0.160s
time perl -lne 'length>=6&&print' file
real 0m4.252s
user 0m3.220s
sys 0m0.164s
sed -r '/^.{,5}$/d' file >out
real 0m7.947s
user 0m7.064s
sys 0m0.120s
./script.py >out
real 0m8.154s
user 0m7.184s
sys 0m0.164s
awk 'length>=6' file
length>=6
: যদি length>=6
সত্য ফেরত দেয়, বর্তমান রেকর্ডটি মুদ্রণ করে।perl -lne 'length>=6&&print' file
lenght>=6
সত্য ফেরত দেয়, বর্তমান রেকর্ডটি মুদ্রণ করে।% cat file
a
bb
ccc
dddd
eeeee
ffffff
ggggggg
% ./foo file 6
ffffff
ggggggg
% awk 'length>=6' file
ffffff
ggggggg
% perl -lne 'length>=6&&print' file
ffffff
ggggggg
awk
সমাধানের জন্য অপেক্ষা করছিলাম ..
sed
সমাধানটি মুছতে হয়েছিল (এটি ঘটে, আমি জানি)। এক্সডি
pos
চলকের বিন্দুটি কী ? আমি এটি line
একটি নতুন লাইন চরিত্রের সাথে চরিত্রটিতে একটি পয়েন্টার ফিরিয়ে দিই , তবে আপনি কখনও এটি ব্যবহার করবেন বলে মনে হয় না। এবং যদি আপনি এটি না পান তবে আপনি এটির সমান সেট করেছেন \0
।
\0
( strchr()
চরিত্রটি না পাওয়া গেলে একটি NULL পয়েন্টার প্রদান করে )। বিন্দুটি প্রতিটি লাইনের শেষে প্রতিটি নিউলাইনকে প্রতিস্থাপন করে \0
যাতে নতুন লাইনটি কখনই গণনা করা হয় না strlen()
: এটি এমন যাতে শেষ লাইনে কোনও সম্ভাব্য অনুপস্থিত নিউলাইন নির্বিশেষে দৈর্ঘ্যটি সর্বদা 6 টির সাথে তুলনা করা যায়। আমি জানি যে শুধুমাত্র শেষ লাইনের সাথে আলাদাভাবে চিকিত্সা করা আরও কার্যকর হবে I আমি সম্ভবত এটি পরে আপডেট করব।
grep
একই ফাইলটিতে সমাধানটি পরীক্ষা করেছি এবং এটি আসলে দ্রুত (সম্ভবত কারণ strlen()
এখানে সেরা ধারণা নয়) । getchar()
পরিবর্তে প্রথম এন অক্ষরটি পরীক্ষা করার জন্য আমি একটি লুপ ব্যবহার করার চেষ্টা করব , আমার ধারণা এটি দৃশ্যমানভাবে উন্নত করা উচিত। এবং হ্যাঁ, বাফারের দৈর্ঘ্যের উপরের কোনও লাইন কেবল বাফারের দৈর্ঘ্যে কাটা হয়।
আপনি প্রাক্তন মোডে ভিম ব্যবহার করতে পারেন:
ex -sc 'v/\v.{6}/d' -cx file
\v
যাদু চালু করুন
.{6}
6 বা ততোধিক অক্ষরের সাথে লাইনগুলি সন্ধান করুন
v
ব্যুত্ক্রমে নির্বাচন
d
মুছে ফেলা
x
সংরক্ষণ করেন এবং বন্ধ করেন
রুবি দ্রবণ:
$ cat input.txt
abcdef
abc
abcdefghijk
$ ruby -ne 'puts $_ if $_.chomp.length() >= 6 ' < input.txt
abcdef
abcdefghijk
সহজ ধারণা: রুবির স্টিডিনে ফাইলটি পুনর্নির্দেশ করুন এবং স্ট্ডিন থেকে প্রিন্ট লাইন কেবল তার দৈর্ঘ্য বড় বা 6 এর সমান হলে