বিশাল ফাইলের শুরু এবং শেষের দিকে লাইন যুক্ত করুন


23

আমার দৃশ্যাবলী রয়েছে যেখানে ভিক্ষাবৃত্তিতে এবং বিশাল ফাইলগুলির শেষের দিকে লাইনগুলি যুক্ত করা যায়।

আমি নীচে প্রদর্শিত হিসাবে চেষ্টা করেছি।

  • প্রথম লাইনের জন্য:

    sed -i '1i\'"$FirstLine" $Filename
  • শেষ লাইনের জন্য:

    sed -i '$ a\'"$Lastline" $Filename  

তবে এই কমান্ডটি নিয়ে সমস্যাটি হ'ল এটি ফাইলের প্রথম লাইন সংযোজন করছে এবং পুরো ফাইলটি ট্র্যাভার করছে। শেষ লাইনের জন্য এটি আবার পুরো ফাইলটি অনুসরণ করে এবং একটি শেষ লাইন সংযোজন করছে। যেহেতু এটির বিশাল ফাইলটি (14 গিগাবাইট) খুব বেশি সময় নিচ্ছে।

কেবল একবার ফাইলটি পড়ার সময় আমি কীভাবে শুরুতে একটি লাইন এবং অন্য একটি ফাইলের শেষে যুক্ত করতে পারি?

উত্তর:


20

sed -iবাস্তবায়নের বিশদ হিসাবে টেম্পাইলগুলি ব্যবহার করে, যা আপনি যা অভিজ্ঞতা নিচ্ছেন; তবে বিদ্যমান সামগ্রীতে ওভাররাইট না করে ডেটা স্ট্রিমের শুরুতে ডেটা প্রিফেন্ডিংয়ের জন্য ফাইলটি পুনর্লিখনের প্রয়োজন, এড়িয়ে যাওয়ার পরেও এটিকে কাছাকাছি পাওয়ার কোনও উপায় নেই sed -i

যদি ফাইলটি পুনরায় লেখার কোনও বিকল্প না হয়, আপনি যখন এটি পড়বেন তখন এটি হেরফেরের বিষয়টি বিবেচনা করতে পারেন, উদাহরণস্বরূপ:

{ echo some prepended text ; cat file ; } | command

এছাড়াও, সেড স্ট্রীমগুলি সম্পাদনার জন্য - কোনও ফাইল কোনও স্ট্রিম নয়। এড বা প্রাক্তনের মতো একটি উদ্দেশ্যে এমন প্রোগ্রাম ব্যবহার করুন। -iসেড করার বিকল্পটি কেবল পোর্টেবলই নয়, এটি আপনার ফাইলে যে কোনও প্রতীকও ভেঙে ফেলবে, যেহেতু এটি মূলত এটি মুছে ফেলে এবং পুনরায় তৈরি করে, যা অর্থহীন।

আপনি এটির edমতো একটি একক আদেশে এটি করতে পারেন:

ed -s file << 'EOF'
0a
prepend these lines
to the beginning
.
$a
append these lines
to the end
.
w
EOF

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


হাই, এড কমান্ড যা আপনি সরবরাহ করেছেন তা বিশাল ফাইলগুলির জন্য খুব ভালভাবে কাজ করছে। তবে আমার কাছে টেস্ট, টেস্ট 1, টেস্ট 2 এর মতো 3 বিশাল ফাইল রয়েছে I $ একটি শেষ পর্যন্ত এই লাইন সংযোজন। ডাব্লু ইওএফ তবে এটি কেবল টেস্ট ফাইল নেবে এবং প্রথম / শেষ লাইন যুক্ত করে। আমরা একই কমান্ডে কীভাবে পরিবর্তন করতে পারি যাতে এটি সমস্ত ফাইলে প্রথম এবং শেষ লাইন যুক্ত করতে হয়।
UNIXbest

@ ইউনিক্সবেস্ট - একটি forলুপ ব্যবহার করুন :for file in Tes*; do [command]; done
ক্রিস ডাউন

হাই ডাউন, আমি টেস * এ ফাইলের জন্য নীচে কমান্ড ব্যবহার করেছি; এড-এস টেস করুন << 'ইওএফ' 0 এ হেলো এইচডিআর। $ একটি হ্যালো টিএলআর। ডাব্লু ইওএফ সম্পন্ন হয়েছে তবে এটি এখনও প্রথম ফাইলটিতে লেখা আছে।
UNIXbest

ঠিক আছে, কারণ আপনার ব্যবহার প্রয়োজন "$file", Tes*তর্ক হিসাবে নয় ed
ক্রিস ডাউন

2
@ ইউনিক্সবেস্ট যদি আপনার উত্তরটি এই সমস্যার সমাধান করে ফেলেছে তবে আপনার এটি গ্রহণ করার কথা বিবেচনা করা উচিত।
জোসেফ আর।

9

মনে রাখবেন যে আপনি যদি ডিস্কে ফাইলটির একটি সম্পূর্ণ অনুলিপি বরাদ্দ এড়াতে চান তবে আপনি এটি করতে পারেন:

sed '
1i\
begin
$a\
end' < file 1<> file

এটি সত্যটি ব্যবহার করে যে যখন তার স্টিডিন / স্টাডআউট কোনও ফাইল হয়, তখন sed ব্লক দিয়ে পড়ে এবং লেখায়। সুতরাং এখানে, এটি যে ফাইলটি পড়ছে তা ওভাররাইড করা ঠিক আছে যতক্ষণ আপনি যুক্ত করছেন প্রথম লাইনটি sedব্লকের আকারের চেয়ে ছোট (4k বা 8k এর মতো কিছু হওয়া উচিত)।

মনে রাখবেন যে কোনও কারণে যদি sedব্যর্থ হয় (নিহত, মেশিন ক্রাশ ...), আপনি অর্ধেক প্রক্রিয়া করা ফাইলটি শেষ করবেন যার অর্থ কিছুটা মাঝখানে কোথাও হারিয়ে যাওয়া প্রথম লাইনের আকারটি হবে।

আরও মনে রাখবেন যে আপনার sedজিএনইউ sedনা হলে এটি বাইনারি ডেটার জন্য কাজ করবে না (তবে যেহেতু আপনি ব্যবহার করছেন -i, আপনি জিএনইউ সেড ব্যবহার করছেন)।


আমার জন্য এই ত্রুটিগুলি উবুন্টু 16.04
সিএসবা তোথ

4

এখানে কয়েকটি পছন্দ রয়েছে (এগুলির সবগুলিই ফাইলের একটি নতুন অনুলিপি তৈরি করবে যাতে আপনার পক্ষে পর্যাপ্ত জায়গা রয়েছে তা নিশ্চিত করুন):

  • সরল প্রতিধ্বনি / বিড়াল

    echo "first" > new_file; cat $File >> new_file; \
      echo "last" >> new_file; 
  • awk / gawk ইত্যাদি

    gawk 'BEGIN{print "first\n"}{print}END{print "last\n"}' $File > NewFile 

    awkএবং এর বিভিন্ন ফাইলগুলি এক-এক লাইনে পঠন করে। BEGIN{}ব্লক প্রথম লাইন আগে মৃত্যুদন্ড কার্যকর করা হয় END{}শেষ লাইনটি পর ব্লক। সুতরাং, উপরের কমান্ডটির অর্থ print "first" at the beginning, then print every line in the file and print "last" at the end

  • পার্ল

    perl -ne 'BEGIN{print "first\n"} print;END{print "last\n"}' $File > NewFile

    এটি মূলত উপরের গোকের মতো ঠিক একই জিনিস যা পার্লটিতে লেখা হয়েছে।


1
মনে রাখবেন যে এই সমস্ত ক্ষেত্রে আপনার নতুন ফাইলের জন্য কমপক্ষে 14 গিগাবাইট বেশি স্থানের প্রয়োজন হবে।
ক্রিস ডাউন

@ ক্রিসডাউন ভাল বিষয়, আমি আমার উত্তর সম্পাদনা করে তা পরিষ্কার করে দিতে পারি। আমি ধরে নিয়েছিলাম যে ওপি ব্যবহার করে sed -iযে কোনও সমস্যা হয়নি কারণ টেম্প ফাইলগুলি তৈরি করে।
টেরডন

3

আমি অনেক সহজ পছন্দ:

gsed -i '1s/^/foo\n/gm; $s/$/\nbar/gm' filename.txt

এটি ফাইলটি রূপান্তর করে:

asdf
qwer

ফাইলটিতে:

foo
asdf
qwer
bar

2

আপনি প্রাক্তন মোডে ভিম ব্যবহার করতে পারেন:

ex -sc '1i|ALFA' -c '$a|BRAVO' -cx file
  1. 1 প্রথম লাইন নির্বাচন করুন

  2. i পাঠ্য এবং নিউলাইন .োকান

  3. $ শেষ লাইনটি নির্বাচন করুন

  4. a পাঠ্য এবং নিউলাইন যুক্ত করুন

  5. x সংরক্ষণ করেন এবং বন্ধ করেন


আমরা একাধিক ফাইলে এটি করতে চাইলে কী হবে?
জিওউইউ

1
@ জাইউজ যা সত্যই এই প্রশ্নের অবকাশ নেই
স্টিভেন পেনি

আপনি কি নিশ্চিত যে এটি% a এবং% a নয়?
কার্লোস রোবলস

2

কোনও ফাইলের শুরুতে ডেটা toোকানোর কোনও উপায় নেই you আপনি যা করতে পারেন তা হ'ল একটি নতুন ফাইল তৈরি করা, অতিরিক্ত ডেটা লিখুন এবং পুরাতন ডেটা যুক্ত করুন। সুতরাং প্রথম লাইনটি সন্নিবেশ করানোর জন্য আপনাকে কমপক্ষে একবার পুরো ফাইলটি আবার লিখতে হবে। আপনি ফাইলটি পুনর্লিখন না করে শেষ লাইনটি যুক্ত করতে পারেন।

sed -i '1i\'"$FirstLine" $Filename
echo "$LastLine" >>$Filename

বিকল্পভাবে, আপনি দুটি কমান্ড দুটি এক সাথে সেডের মিশ্রিত করতে পারেন।

sed -i -e '1i\'"$FirstLine" -e '$ a\'"$Lastline" $Filename

sed -iএকটি নতুন আউটপুট ফাইল তৈরি করে এবং তারপরে এটি পুরানো ফাইলের উপরে সরিয়ে দেয়। এর অর্থ হল যে সেড কাজ করার সময়, স্থানটি ব্যবহার করে ফাইলটির একটি অনুলিপি রয়েছে। আপনি ফাইলটি জায়গায় জায়গায় ওভাররাইট করে এড়াতে পারবেন , তবে বড় সীমাবদ্ধতার সাথে: আপনি যে লাইনটি যুক্ত করছেন সেটি শেডের বাফারের চেয়ে ছোট হতে হবে এবং যদি আপনার সিস্টেমটি ক্র্যাশ করে তবে আপনি ক্ষতিগ্রস্থ ফাইল এবং এতে থাকা কিছু সামগ্রী হারিয়ে ফেলতে পারেন end মাঝখানে, তাই আমি দৃ against়ভাবে এর বিরুদ্ধে সুপারিশ।

¹ লিনাক্সের কোনও ফাইলের মধ্যে ডেটা to োকানোর উপায় রয়েছে তবে এটি কেবলমাত্র পুরো ফাইল সংখ্যা ব্লক সন্নিবেশ করতে পারে, এটি স্বেচ্ছা দৈর্ঘ্যের স্ট্রিংগুলি সন্নিবেশ করতে পারে না। এটি ডেটাবেস এবং ভার্চুয়াল মেশিনের মতো কিছু অ্যাপ্লিকেশনের জন্য দরকারী তবে এটি পাঠ্য ফাইলের জন্য অকেজো।


সত্য না. আধুনিক কার্নেলগুলিতে এক্সএফএস এবং ext4- এ উপলব্ধ fallocate()সাথে দেখুন FALLOC_FL_INSERT_RANGE(4.xx) man7.org/linux/man-pages/man2/fallocon.2.html
এরিক

@ এরিক আপনি কেবলমাত্র পুরো ব্লকগুলি সন্নিবেশ করতে পারেন, যদিও স্বেচ্ছাসেবী বাইট দৈর্ঘ্য নয়, কমপক্ষে লিনাক্স 4.15.0 এ এক্সট্রোল সহ। এমন কোনও ফাইল সিস্টেম রয়েছে যা স্বেচ্ছায় বাইট দৈর্ঘ্য সন্নিবেশ করতে পারে?
গিলস 22

ঠিক আছে তবে এটি এখনও আপনার বক্তব্যকে সঠিক করে না। আপনি লিখেছেন: "কোনও ফাইলের শুরুতে ডেটা toোকানোর কোনও উপায় নেই"। এটি এখনও সত্য নয়: একটি ফাইলের শুরুতে এক্সটেন্টগুলি toোকানোর জন্য একটি ব্যবস্থা আছে। এটি অবশ্যই সাবধান, তবে এটি উল্লেখ করার মতো কারণ কিছু ব্যবহারকারী শূন্যস্থান বা গাড়ীর রিটার্ন দিয়ে ভরাট করে ব্লক আকারের বিধিনিষেধের কথা চিন্তা করে না।
এরিক

0
$ (echo "Some Text" ; cat file1) > file2

4
কেবল কোড উত্তর গ্রহণযোগ্য নয়, দয়া করে আপনার উত্তরটি উন্নত করুন
নেটওয়ার্কার

আপনার পরামর্শের ব্যাখ্যা বা ডকুমেন্টেশনের লিঙ্কগুলি অন্তর্ভুক্ত করার জন্য যা আপনার সমাধানকে সমর্থন করে আপনার উত্তরকে প্রসারিত করার বিষয়ে বিবেচনা করুন।
হ্যালোসঘস্ট

-1

আধুনিক লিনাক্স কার্নেলগুলি (৪.১ বা ৪.২ এর চেয়ে বেশি) fallocate()সিস্টেমের মাধ্যমে FALLOC_FL_INSERT_RANGEext4 এবং xfs ফাইল সিস্টেমের মাধ্যমে একটি ফাইলের শুরুতে তথ্য সন্নিবেশ করানো সমর্থন করে। সংক্ষেপে এটি একটি লজিকাল শিফটিং অপারেশন: ডেটা যৌক্তিকভাবে একটি উচ্চ অফসেটে স্থানান্তরিত হয়।

আপনি ফাইলের শুরুতে যে সীমাটি সন্নিবেশ করতে চান তার গ্রানুলারিটি সম্পর্কিত একটি সীমাবদ্ধতা বিদ্যমান। তবে পাঠ্য ফাইলের জন্য আপনি সম্ভবত প্রয়োজনের তুলনায় কিছুটা বেশি বরাদ্দ করতে পারেন (গ্রানুলারিটির সীমানা অবধি) এবং ফাঁকা জায়গা বা গাড়ীর রিটার্ন পূরণ করতে পারেন তবে এটি আপনার প্রয়োগের উপর নির্ভর করে

আমি সহজেই উপলভ্য এমন কোনও লিনাক্স ইউটিলিটি সম্পর্কে জানি না যা ফাইলের এক্সটেন্টগুলি পরিচালনা করে তবে এটি লিখতে অসুবিধা হয় না: একটি ফাইল বর্ণনাকারী পান এবং fallocate()উপযুক্ত যুক্তি দিয়ে কল করুন । আরও তথ্যের জন্য fallocateসিস্টেম কলের ম্যান পৃষ্ঠাটি দেখুন : http://man7.org/linux/man-pages/man2/fallocon.2.html


একটি ইউটিলিটি সমস্যা নয় (এম্বেডড লিনাক্স অনুমান করে): ইউজু-লিনাক্সটিতে একটি fallocateইউটিলিটি রয়েছে । সমস্যাটি হ'ল পুরো ব্লকের গ্রানুলারিটি বেশিরভাগ পাঠ্য ফাইলের জন্য এটি অকেজো করে তোলে। আর একটি সমস্যা হ'ল পরিসীমা বরাদ্দ এবং পরবর্তী পরিবর্তনগুলি পারমাণবিক নয়। সুতরাং এটি আসলে এখানে সমস্যার সমাধান করে না।
গিলস 22

গ্রানুলারিটি হ'ল একটি সতর্কতা যা আমি ইতিমধ্যে উল্লেখ করেছি এবং না, এটি এটি অকেজো করে না, এটি প্রয়োগের উপর নির্ভর করে। পারমাণবিকতা গুরুত্বপূর্ণ যে প্রশ্নে আপনি কোথায় দেখেছেন? আমি পারফরম্যান্সের সমস্যাটিই দেখতে পাচ্ছি। তবুও এই সিস্কেলটি পারমাণবিক বলে মনে হচ্ছে: elixir.bootlin.com/linux/latest/source/fs/open.c#L228 এবং যদি পারমাণবিকতা গুরুত্বপূর্ণ হয়ে ওঠে (তবে তা নয়, তবে বলুন এটি যুক্তির জন্যই) শুধু ফাইল লকিং ব্যবহার করুন। (আমাকে কার্নেল কোডের সেই জায়গায় চিহ্নিত করুন যেখানে fallocateপারমাণবিকতা ভঙ্গ হয়ে গেছে, দয়া করে আমি কৌতূহলী)
এরিক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.