একটি খুব বড় ফাইল স্ট্রিং প্রতিস্থাপন


10

নীচের মতো একই ফর্ম্যাটে আমার কোনও বিচ্ছেদী চরিত্রহীন url এর একটি দীর্ঘ সিরিজ রয়েছে:

http://example.comhttp://example.nethttp://example.orghttp://etc...

আমি প্রতিটি URL একটি নতুন লাইনে থাকতে চাই be আমি "http: //" এর সমস্ত দৃষ্টান্ত "\ nhttp: //" এর সাথে সেড ব্যবহার করে এটি করার চেষ্টা করেছি

sed 's_http://_\nhttp://_g' urls.txt

তবে একটি সেগমেন্টেশন ত্রুটি ঘটে (মেমরি লঙ্ঘন)। আমি কেবল এটিই অনুধাবন করতে পারি যে ফাইলটির নিছক আকার (এটি 100 গিগাবাইটের বেশি) এর ফলে কিছুটা সীমা অতিক্রম করছে।

প্রসেসিংয়ের জন্য আমি ফাইলটি কয়েকটি ছোট ফাইলগুলিতে বিভক্ত করতে পারি, তবে "HTTP: //" এর সমস্ত দৃষ্টান্ত অক্ষত রাখতে হবে।

এই কাজ করতে একটি ভাল উপায় আছে কি?


আমার মনে হয় সেড লাইন এন্ডিং ছাড়াই 100 গিগাবাইট পছন্দ করে না কারণ এটি তার বাফারে একটি লাইন পড়ার চেষ্টা করে।
জিপ্পি

বিভাজন ("কাটাটি যেখানেই ঘটে" নির্বিশেষে), প্রক্রিয়াজাতকরণ, তারপরে পুনরায় সমাবেশ করা উচিত তবে সঠিক ফলাফল দেওয়া উচিত।
enzotib

3
যদি আপনার কাছে সত্যিকার অর্থে 100 গিগাবাইট পাঠ্য ফাইল থাকে যা একটি একক দীর্ঘ লাইন থাকে তবে আপনি কাজটি করার জন্য একটি দ্রুত সি প্রোগ্রাম লিখতে ভাল।
এফএমপুরফি

উত্তর:


11

সঙ্গে awkআপনি একসাথে টেক্সট বিপুল পরিমাণ পড়া এড়াতে পারেন:

awk -vRS='http://' -vORS='\nhttp://' 1 urls.txt > urlsperline.txt

সাফল্য ব্যবহৃত awkবাস্তবায়নের উপর নির্ভর করে । উদাহরণস্বরূপ gawk, সূক্ষ্ম কাজ করে তবে mawkক্রাশ হয়।


6

এটি কাজটি করবে:

perl -pe 'BEGIN { $/ = "//" } s!(?=http://\z)!\n!' urls.txt

Setting / সেট করে , আমি একটি লাইনের সংজ্ঞা পরিবর্তন করেছি যাতে এটি //একটি নতুন লাইনের পরিবর্তে শেষ হয় । এটি পার্লকে একবারে একটি করে ইউআরএল পড়তে বাধ্য করে। কোনও ইউআরএলে //স্কিমটি বাদ দিলে এর সম্ভাবনা কম। তবে এটি ঠিক আছে যদি কেউ এটি করে তবে রেজেক্স এটিকে জালিয়াতিপূর্ণ নিউলাইনগুলি যোগ করা থেকে বিরত রাখবে।

যদি আপনি প্রথম URL টির আগে একটি ফাঁকা রেখা যোগ করা এড়াতে চান:

perl -pe 'BEGIN { $/ = "//"; print scalar <> } s!(?=http://\z)!\n!' urls.txt

আপনি s!http://\z!\nhttp://!দ্রুত কিনা তা দেখতে আপনি বেঞ্চমার্কিংয়ের চেষ্টা করতে পারেন । তারা সমান দ্রষ্টব্য যে /gপ্রতিস্থাপনে পতাকাটি প্রয়োজনীয় নয়, কারণ "প্রতি লাইনে" কেবল একটি মিল থাকতে পারে।


পার্ল রিজেক্সপ ইঞ্জিনটি কি বহু-গিগাবাইট-দীর্ঘ লাইনগুলির সাথে ঠিক আছে?
অ্যালেক্সিয়াস

2
@ অ্যালেক্সিয়াস, সম্ভবত না, তবে এটি হওয়ার দরকার নেই। যেহেতু আমি পরিবর্তন করেছি $/, এটি একবারে কেবলমাত্র একটি ইউআরএল নিয়ে কাজ করবে।
সিজেএম

আহ, আমি দেখছি আপনি সেখানে কি করেছেন। 90 এর দশক থেকে এটি কিছুটা সময় হয়ে গেছে, এবং আমারও করতে হয়েছিল man perlvar, তবে এটি সেভাবেই উপলব্ধি করে।
অ্যালেক্সিয়স

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

@ জো, আমি রেজেক্সে http:অংশটি পরীক্ষা করছি । এটি প্রতিটি পরীক্ষা করে দেখবে //, তবে এটি না পেলে এটি কোনও নতুন লাইন যুক্ত করবে না http://
সিজেএম

5
  1. :ফাইলটি কাটাতে নতুন লাইনের সাহায্যে এর সমস্ত উপস্থিতি পরিবর্তন করুন।
  2. প্রতিস্থাপন করা
    • http সাথে লাইন শেষে
    • একটি নতুন লাইন অনুসরণ করে http:এবং এর পরের লাইনটি যুক্ত করুন
  3. একবারে পুনরাবৃত্তি করুন, সুতরাং সম এবং বিজোড় লাইনগুলি আপডেট করা হয়

এই পদক্ষেপগুলি দেখতে দেখতে:

tr ':' '\n' | sed -e '/http$/{N;s/http\n/\nhttp:/}' | sed -e '/http$/{N;s/http\n/\nhttp:/}'
  1. এমন লাইন রয়েছে কিনা তা পরীক্ষা করে দেখুন http://, লাইন নম্বরগুলি মুদ্রণ করুন। এটি কেবল তখনই ঘটতে পারে যখন: ইউআরএলটির বাইরে অন্য কোথাও থাকলে http

    grep -nv '^http://'

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.