বিশাল ফাইলগুলিতে স্ট্রিংকে নতুন লাইন যুক্ত করুন


16

"বাইনারি" অনুসন্ধান / স্ট্রিংগুলিকে কিছুটা মেমোরি-দক্ষ উপায়ে প্রতিস্থাপন করার জন্য কোনও লাইন-ভিত্তিক সরঞ্জাম সম্পর্কে কেউ জানেন? এই প্রশ্নটি দেখুন ।

আমার কাছে একটি + 2GB টেক্সট ফাইল রয়েছে যা আমি এটি করতে যা প্রদর্শিত হবে তার অনুরূপ প্রক্রিয়া করতে চাই:

sed -e 's/>\n/>/g'

এর অর্থ, আমি ক এর পরে ঘটে যাওয়া সমস্ত নিউলাইনগুলি মুছে ফেলতে চাই >, তবে অন্য কোথাও নয়, যাতে এটি বাতিল হয়ে যায় tr -d

এই আদেশটি (যা আমি অনুরূপ প্রশ্নের উত্তর থেকে পেয়েছি ) এর সাথে ব্যর্থ হয় couldn't re-allocate memory:

sed --unbuffered ':a;N;$!ba;s/>\n/>/g'

সুতরাং, সি অবলম্বন ছাড়া অন্য কোন পদ্ধতি আছে? আমি পার্লকে ঘৃণা করি তবে এই ক্ষেত্রে ব্যতিক্রম করতে রাজি আছি :-)

আমি এমন কোনও চরিত্রের তথ্য জানি না যা ডেটাতে ঘটে না, তাই \nঅন্য চরিত্রের সাথে অস্থায়ী প্রতিস্থাপন করা এমন কিছু যা আমি সম্ভব হলে এড়াতে চাই।

কোন ভাল ধারণা, কেউ?


আপনি কি বিকল্প চেষ্টা করেছেন --unbuffered?
ctrl-alt-delor

--unbufferedস্মৃতি ছাড়াই বা ছাড়াই
ম্যাটবিয়ানকো

কি করে $!?
ctrl-alt-delor

প্রথম সেড কমান্ড দিয়ে কি ভুল হচ্ছে। দ্বিতীয়টি মনে হয় সবকিছুকে প্যাটার্ন স্পেসে পড়ছে, আমি জানি না যে $!যদিও এটি। আমি আশা করি এটির প্রচুর স্মৃতি দরকার।
ctrl-alt-delor

সমস্যাটি হ'ল সেড সবকিছু লাইন হিসাবে পড়েন, এ কারণেই প্রথম কমান্ড নতুন লাইনগুলি সরিয়ে দেয় না, যেহেতু এটি পাঠ্যটিকে সারি-সারি-সারি আবার আউটপুট করে। দ্বিতীয় কমান্ডটি হ'ল একমাত্র কাজ আমি মনে করি sedএই ক্ষেত্রে উপযুক্ত সরঞ্জাম নয়।
ম্যাটবিয়ানকো

উত্তর:


14

পার্লে এটি সত্যিই তুচ্ছ, আপনার এটি ঘৃণা করা উচিত নয়!

perl -i.bak -pe 's/>\n/>/' file

ব্যাখ্যা

  • -i: জায়গায় জায়গায় ফাইল সম্পাদনা করুন, এবং কল করা মূল একটি ব্যাকআপ তৈরি করুন file.bak। আপনি যদি ব্যাকআপ না চান তবে কেবল perl -i -peপরিবর্তে ব্যবহার করুন।
  • -pe: লাইন দ্বারা ইনপুট ফাইল লাইন পড়ুন এবং হিসাবে দেওয়া স্ক্রিপ্ট প্রয়োগ করার পরে প্রতিটি লাইন মুদ্রণ -e
  • s/>\n/>/: প্রতিস্থাপন, ঠিক যেমন sed

এবং এখানে একটি awkপদ্ধতির:

awk  '{if(/>$/){printf "%s",$0}else{print}}' file2 

3
+1 টি। awk গল্ফ:awk '{ORS=/>$/?"":"\n"}1'
গ্লেন জ্যাকম্যান

1
আমি কেন পার্লকে সাধারণভাবে অপছন্দ করি সে কারণেই কেন আমি এই উত্তরটি বেছে নিই (বা আসলে জ্ঞানকের উত্তর সম্পর্কে আপনার মন্তব্য): পঠনযোগ্যতা। একটি সাধারণ "সেড প্যাটার্ন" দিয়ে পার্ল-পেপ ব্যবহার করা জটিল সেড-এক্সপ্রেশনের চেয়ে আরও বেশি পঠনযোগ্য।
ম্যাটবিয়ানকো

3
@ ম্যাটবিয়ানকো যথেষ্ট মেলা কিন্তু, ঠিক তাই আপনি জানেন, পার্লের সাথে এর কোনও যোগসূত্র নেই। জ্নুক যে চেহারাটির পিছনে ব্যবহার করেছেন তা হ'ল কিছু নিয়মিত প্রকাশের ভাষার বৈশিষ্ট্য (পিসিআরই সহ তবে সীমাবদ্ধ নয়), পার্লের দোষ মোটেও নয়। এছাড়াও, ':a;N;$!ba;s/>\n/>/g'আপনার প্রশ্নে এই কুক্ষ্মবাদী একত্বকে বৈশিষ্ট্যযুক্ত করার পরে , আপনি পঠনযোগ্যতা সম্পর্কে অভিযোগ করার অধিকারটি ছাড় দিয়েছেন! : P: P
terdon

@glennjackman সুন্দর! আমি foo ? bar : bazকনস্ট্রাক্টের সাথে খেলছিলাম তবে এটি কাজ করতে পারা যায় না।
টেরডন

@ এটারডন: ইয়াপ, আমার ভুল মুছে ফেল.
cuonglm

7

একটি perlসমাধান:

$ perl -pe 's/(?<=>)\n//'

Explaination

  • s/// স্ট্রিং প্রতিস্থাপনের জন্য ব্যবহৃত হয়।
  • (?<=>) প্যাটার্নহাইন্ড প্যাটার্ন
  • \n নতুন লাইনের সাথে মেলে।

পুরো প্যাটার্নটির অর্থ এর >আগে থাকা সমস্ত নিউলাইন মুছে ফেলা হচ্ছে ।


2
প্রোগ্রাম অংশগুলি কি মন্তব্য করতে যত্নশীল? আমি সবসময় শিখতে খুঁজছি।
ম্যাটবিয়ানকো

2
চেহারার পিছনে কেন বিরক্ত করবেন? শুধু কেন নয় s/>\n/>/?
টেরডন

1
বা s/>\K\n//এছাড়াও কাজ করবে
গ্লেন জ্যাকম্যান

@ ইটারডন: আমি প্রথমে প্রথমে, পরিবর্তনের পরিবর্তে অপসারণ করব
কিউংলম

@্লেগনজ্যাকম্যান: ভালো কথা!
cuonglm

3

এটি সম্পর্কে:

sed ':loop
  />$/ { N
    s/\n//
    b loop
  }' file

জিএনইউ সেডের জন্য, আপনি প্রশ্ন অনুযায়ী -u( --unbuffered) বিকল্পটি যুক্ত করার চেষ্টা করতে পারেন । সাধারণ ওয়ান লাইনার হিসাবে GNU সেড এতে খুশিও:

sed ':loop />$/ { N; s/\n//; b loop }' file

\nফাইলটি শেষ হয়ে গেলে এটি শেষটি সরিয়ে দেয় না >\n, তবে সম্ভবত এটি তত ভাল।
স্টাফেন চেজেলাস

@ স্টাফেনচাজেলাস, কেন সমাপ্তিটি }পৃথক মত প্রকাশের প্রয়োজন? এটি কি বহুমাত্রিক অভিব্যক্তি হিসাবে কাজ করবে না?
গ্রিম

1
যে সঙ্গে POSIX seds কাজ করবে b loop\n}বা -e 'b loop' -e '}'না হিসাবে b loop;}এবং অবশ্যই না b loop}কারণ }এবং ;ট্যাগ নামে বৈধ (যদিও তাদের অধিকার মনে কেউ এটা ব্যবহার করেন। এবং তার মানে গনুহ sed POSIX conformant নয়) এবং }কমান্ড চাহিদা বিচ্ছিন্ন হতে bকমান্ড থেকে ।
স্টাফেন চেজেলাস

@ স্টাফেনচাজেলাস, জিএনইউ sedউপরোক্ত সকলের সাথেও খুশি --posix! স্ট্যান্ডার্ডটিতে ব্রেস এক্সপ্রেশনগুলির জন্য নিম্নলিখিতগুলিও রয়েছে - The list of sed functions shall be surrounded by braces and separated by <newline>s। এর অর্থ কি এই নয় যে সেমিকোলনগুলি কেবল ধনুর্বন্ধকের বাইরে ব্যবহার করা উচিত?
গ্রিম

@ মিমকিজার, ক্রমাগত লাইনগুলি শেষ হওয়ার জন্য লুপটি দরকার >। মূলটির কোনওটিই ছিল না, এটি স্টাফেনই দেখিয়েছিলেন।
গ্রিম

1

কমান্ডটি ব্যবহার sedকরে আপনার সক্ষম হওয়া উচিত N, তবে কৌশলটি হ'ল প্রতিবার অন্য যোগ করার সময় প্যাটার্ন স্পেস থেকে একটি লাইন মুছে ফেলা হবে (যাতে প্যাটার্ন স্পেসটি সর্বদা পুরোটা পড়ার চেষ্টা না করে কেবলমাত্র 2 টি পরপর রেখা থাকে ফাইল) - চেষ্টা করুন

sed ':a;$!N;s/>\n/>/;P;D;ba'

সম্পাদনা: পিটারিস ক্রুমিন্সের বিখ্যাত সেড ওয়ান- লাইনার পুনরায় পড়ার পরে ব্যাখ্যা করা হয়েছে যে আমি বিশ্বাস করি এর থেকে আরও ভাল sedসমাধান হবে

sed -e :a -e '/>$/N; s/\n//; ta'

এটি কেবলমাত্র নিম্নের রেখাটি সংযোজন করে যা ইতিমধ্যে >শেষের দিকে একটি ম্যাচ তৈরি করেছে , এবং একটানা মিলে যাওয়া লাইনগুলির কেস পরিচালনা করতে শর্তসাপেক্ষে ফিরে লুপ করা উচিত (এটি ক্রুমিনের 39।) যদি একটি ব্যাকস্ল্যাশ দিয়ে শেষ হয় তবে পরবর্তীটিতে একটি লাইন যুক্ত করুন "\" ঠিক এর প্রতিকল্পন ছাড়া >জন্য \চরিত্রেও যোগদান, এবং সত্য যে যোগদানের চরিত্র আউটপুটে বজায় রাখা হয়)।


2
>টানা 2 লাইন শেষ হয়ে গেলে এটি কাজ করে না (এটি জিএনইউ নির্দিষ্টও রয়েছে)
স্টাফেন চেজেলাস

1

sedচূড়ান্ত নিউলাইন ছাড়া আউটপুট নির্গত করার উপায় সরবরাহ করে না। আপনার পদ্ধতির Nমৌলিকভাবে কাজ করে তবে মেমোরিতে অসম্পূর্ণ রেখাগুলি সঞ্চয় করে এবং লাইনগুলি দীর্ঘ হয়ে গেলে এইভাবে ব্যর্থ হতে পারে (সেড ইমপ্লেনশনগুলি সাধারণত অত্যন্ত দীর্ঘ লাইনগুলি হ্যান্ডেল করার জন্য ডিজাইন করা হয় না)।

পরিবর্তে আপনি awk ব্যবহার করতে পারেন।

awk '{if (/<$/) printf "%s", $0; else print}'

একটি বিকল্প পদ্ধতির মধ্যে হ'ল trনতুন লাইনের চরিত্রটি "বোরিং", ঘন ঘন ঘটে যাওয়া চরিত্রের সাথে অদলবদল করা। স্পেস এখানে কাজ করতে পারে - এমন একটি চরিত্র চয়ন করুন যা প্রতিটি লাইনে প্রদর্শিত হতে পারে বা আপনার ডেটাতে কমপক্ষে একটি বৃহত অনুপাত রেখায় উপস্থিত থাকে।

tr ' \n' '\n ' | sed 's/> />/g' | tr '\n ' ' \n'

উভয় পদ্ধতি ইতিমধ্যে এখানে প্রদর্শিত হয়েছে অন্য উত্তরের আরও কার্যকরভাবে প্রভাবিত করার জন্য। এবং তার সাথে তার পদ্ধতির sed2.5 গিগাবাইট বাফার ছাড়া কাজ করে না।
মাইকজার্ভ

কেউ কি বিশ্রী উল্লেখ করেছেন? ওহ, আমি এটি মিস করেছি, আমি কেবল কোনও কারণে টেরডনের উত্তরে পার্ল লক্ষ্য করেছি। trমাইক্রোসার্ভ - এ পদ্ধতির কোনও উল্লেখ নেই , আপনি একটি আলাদা (বৈধ, তবে কম জেনেরিক) পদ্ধতির পোস্ট করেছেন যা ব্যবহারের ক্ষেত্রেও ঘটে tr
গিলস 'খারাপ হয়ে যাওয়া বন্ধ করুন'

আপনার কাছে বৈধ, তবে কম জেনেরিক শব্দ যেমন আপনি এটিকে কেবল একটি কার্যকরী, লক্ষ্যযুক্ত সমাধান বলেছিলেন আমি যে এই ধরনের একটি জিনিস নয তর্ক তার কঠিন মনে দরকারী যা বিজোড় কারণ এটি 0 upvotes হয়েছে। আমার নিজের সমাধান এবং আপনার আরও জেনেরিক অফারগুলির মধ্যে আমি দেখতে পাচ্ছি সবচেয়ে বড় পার্থক্যটি হ'ল খনিটি বিশেষত কোনও সমস্যা সমাধান করে, তবে আপনার সম্ভবত সাধারণত। এটি এটিকে সার্থক করে তুলতে পারে - এবং আমি আমার ভোটটিও বিপরীত করতে পারি - তবে তাদের সাথে 7 ঘন্টা এবং আপনার উত্তরগুলির পুনরাবৃত্ত থিমের মধ্যে অন্যদের অনুকরণ করে এমন এক বিস্ময়কর বিষয়ও রয়েছে। আপনি এই ব্যাখ্যা করতে পারেন?
মাইকজার্ভ



-1

এটি করার অনেকগুলি উপায় রয়েছে এবং বেশিরভাগ এখানে সত্যই ভাল তবে আমি মনে করি এটি আমার প্রিয়:

tr '>\n' '\n>' | sed 's/^>*//;H;/./!d;x;y/\n>/>\n/'

অথবা এমনকি:

tr '>\n' '\n>' | sed 's/^>*//' | tr '\n>' '>\n'

আমি আপনার কাজের প্রথম উত্তরটি আদৌ পেতে পারি না। আমি যখন দ্বিতীয়টির কমনীয়তার প্রশংসা করি তখনও আমি বিশ্বাস করি যে আপনার এটি অপসারণ করা দরকার *। এটি এখন যেভাবে রয়েছে, এটি একটি দিয়ে শেষ হওয়া লাইনের পরে কোনও ফাঁকা রেখা মুছে ফেলবে >। … হুম। প্রশ্নটির দিকে ফিরে তাকালে আমি দেখতে পাচ্ছি যে এটি কিছুটা অস্পষ্ট। প্রশ্নটি বলে, "আমি ক এর পরে ঘটে যাওয়া সমস্ত নিউলাইনগুলি মুছে ফেলতে চাই >, ..." আমি ব্যাখ্যা করি এর অর্থ এটি >\n\n\n\n\nfooপরিবর্তন করা উচিত \n\n\n\nfooতবে আমি মনে করি fooপছন্দসই আউটপুট হতে পারে।
স্কট

@ স্কট - আমি নিম্নলিখিতগুলিতে বিভিন্নতা নিয়ে পরীক্ষা করেছি: printf '>\n>\n\n>>\n>\n>>>\n>\nf\n\nff\n>\n' | tr '>\n' '\n>' | sed 's/^>*//;H;/./!d;x;y/\n>/>\n/'- ফলাফলটি >>>>>>>>>>f\n\nff\n\nপ্রথম উত্তর দিয়ে আমার জন্য ফলাফল করে । আপনি এটি ভাঙ্গতে যা করছেন তা সত্ত্বেও আমি আগ্রহী, কারণ আমি এটি ঠিক করতে চাই। দ্বিতীয় বিষয় হিসাবে - আমি সম্মত নই যে এটি অস্পষ্ট। ওপি মুছে ফেলার জন্য জিজ্ঞাসা করা হয় না সব > পূর্ববর্তী একটি \newline, কিন্তু এর পরিবর্তে মুছে ফেলার জন্য সব \n ewlines নিম্নলিখিত একটি>
মাইকসার্ভ

1
হ্যাঁ, তবে একটি বৈধ ব্যাখ্যাই হ'ল, এ এর >\n\n\n\n\nপরে কেবল প্রথম নিউলাইন after> ; অন্যরা সবাই অন্যান্য নিউলাইন অনুসরণ করছে। দ্রষ্টব্য যে ওপির "এটিই আমি চাই, যদি এটি কাজ করে তবেই" পরামর্শ ছিল sed -e 's/>\n/>/g', না sed -e 's/>\n*/>/g'
স্কট

1
@ স্কট - পরামর্শটি কার্যকর হয়নি এবং কখনই পারেনি। আমি বিশ্বাস করি না যে কেউ কোডটি পুরোপুরি বোঝে না তার কোড পরামর্শটি সেই ব্যক্তি যে সরল ভাষা ব্যবহার করেন সে হিসাবে এটি ব্যাখ্যা করার মতো বিষয় হিসাবে বিবেচিত হতে পারে। আর তাছাড়া আউটপুট - যদি এটা আসলে কাজ - এর s/>\n/>/উপর >\n\n\n\n\nএখনো এমন কিছু বিষয় যা হবে s/>\n/>/হায় সম্পাদনা করুন।
মাইকজার্ভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.