একে অপরের কাছে বিশাল ফাইলগুলি অনুলিপি না করে যুক্ত করুন


41

এখানে 5 টি বিশাল ফাইল (ফাইল 1, ফাইল 2, .. ফাইল 5) প্রায় 10 জি প্রতিটি এবং অত্যন্ত স্বল্প ফাঁকা স্পেসটি ডিস্কে ছেড়ে যায় এবং আমার এই সমস্ত ফাইলকে একটিতে যুক্ত করতে হবে। আসল ফাইলগুলি রাখার দরকার নেই, কেবল চূড়ান্ত।

catফাইলগুলির ক্রমানুসারে সাধারণ কনটেন্টেশন চলছে file2... file5:

cat file2 >> file1 ; rm file2

দুর্ভাগ্যক্রমে এই পথে কমপক্ষে 10 জি ফ্রি স্পেস দরকার। ফাইলগুলি প্রকৃত অনুলিপি না করেই সংযুক্ত করার কোনও উপায় আছে তবে ফাইল সিস্টেমটি কোনওভাবে বলুন যে ফাইল 1 মূল ফাইল 1 এর শেষে শেষ হয় না এবং ফাইল 2 শুরুতে চালিয়ে যায়?

গীত। ফাইল সিস্টেমটি যদি গুরুত্বপূর্ণ হয় তবে ext4।


2
আমি সমাধান দেখতে আগ্রহী, তবে আমার সন্দেহ হয় যে সরাসরি ফাইল সিস্টেমের সাথে গোলযোগ না করে এটি সম্ভব নয়।
কেভিন

1
আপনার এত বড় একটি একক শারীরিক ফাইল থাকা দরকার কেন? আমি জিজ্ঞাসা করছি কারণ আপনি সম্ভবত এলোমেলো এড়াতে পারবেন - যা বর্তমান উত্তরগুলি দেখায়, বেশ বিরক্তিকর।
লাইওরি

6
@ রশ: তাহলে এই উত্তরটি সাহায্য করতে পারে: serverfault.com/a/487692/16081
লাইওরি

1
ডিভাইস-ম্যাপারের বিকল্প, কম দক্ষ, তবে প্রয়োগ করা সহজ এবং একটি পার্টিশনযোগ্য ডিভাইসে ফলাফল এবং একটি দূরবর্তী মেশিন থেকে ব্যবহার করা যেতে পারে "মাল্টি" মোড ব্যবহার করা nbd-server
স্টাফেন চেজেলাস

1
যখন আমি বলি যে এটি শীতল হওয়া উচিত বলে তারা আমাকে সর্বদা বোকা বলে।
n611x007

উত্তর:


19

আফাইক (দুর্ভাগ্যক্রমে) প্রথম থেকেই কোনও ফাইল কেটে ফেলা সম্ভব নয় (এটি স্ট্যান্ডার্ড সরঞ্জামগুলির ক্ষেত্রে সত্য হতে পারে তবে সিস্কেল স্তরের জন্য এখানে দেখুন )। তবে কিছু জটিলতা যুক্ত করার সাথে আপনি সাধারণ কাটা ব্যবহার করতে পারেন (একসাথে স্পার্স ফাইল সহ): আপনি সমস্ত ডেটা না লিখেই লক্ষ্য ফাইলের শেষে লিখতে পারেন।

আসুন ধরে নেওয়া যাক প্রথমে উভয় ফাইল হুবহু 5GiB (5120 MiB) এবং আপনি একবারে 100 MiB স্থানান্তর করতে চান। আপনি একটি লুপ কার্যকর করেন যা এতে অন্তর্ভুক্ত থাকে

  1. লক্ষ্য ফাইলের শেষে সোর্স ফাইলের প্রান্ত থেকে একটি ব্লক অনুলিপি করা (ডিস্কের স্পেস বাড়ানো)
  2. উত্স ফাইলটি একটি ব্লক (ডিস্কের স্থান মুক্ত করে) কেটে ফেলা হচ্ছে

    for((i=5119;i>=0;i--)); do
      dd if=sourcefile of=targetfile bs=1M skip="$i" seek="$i" count=1
      dd if=/dev/zero of=sourcefile bs=1M count=0 seek="$i"
    done
    

তবে প্রথমে ছোট টেস্ট ফাইল দিয়ে চেষ্টা করে দেখুন, দয়া করে ...

সম্ভবত ফাইলগুলি একই আকার বা ব্লকের আকারের গুণক নয়। সেক্ষেত্রে অফসেটের গণনা আরও জটিল হয়ে যায়। seek_bytesএবং skip_bytesতারপর ব্যবহার করা উচিত।

আপনি যদি এই পথে যেতে চান তবে বিশদগুলির জন্য সহায়তা প্রয়োজন তবে আবার জিজ্ঞাসা করুন।

সতর্কতা

ddব্লকের আকারের উপর নির্ভর করে ফলস্বরূপ ফাইলটি খণ্ডিত দুঃস্বপ্ন হবে।


দেখে মনে হচ্ছে এটি ফাইলগুলি সংযুক্ত করার সবচেয়ে গ্রহণযোগ্য উপায়। পরামর্শের জন্য ধন্যবাদ.
রাশ

3
যদি কোনও স্পার্স ফাইল সমর্থন না থাকে তবে আপনি দ্বিতীয় ফাইলটি যথাযথভাবে বিপরীত করতে পারেন এবং তারপরে কেবল শেষ ব্লকটি সরিয়ে দ্বিতীয় ফাইলে যুক্ত করতে পারেন
ratchet freak

1
আমি নিজে এটি চেষ্টা করে দেখিনি (যদিও আমি প্রায় আসছি), তবে seann.herdejurgen.com/resume/samag.com/html/v09/i08/a9_l1.htm একটি পার্ল স্ক্রিপ্ট যা এই অ্যালগরিদম বাস্তবায়নের দাবি করে।
zwol

16

একসাথে ফাইলগুলি একটি ফাইলে ক্যাটিংয়ের পরিবর্তে, যদি আপনার প্রোগ্রামটি একাধিক ফাইল পরিচালনা করতে না পারে তবে একটি নামী পাইপের সাহায্যে একক ফাইলকে সিমুলেট করুন।

mkfifo /tmp/file
cat file* >/tmp/file &
blahblah /tmp/file
rm /tmp/file

হউকের পরামর্শ অনুসারে, হেরে যাওয়া / ডিএমসেটআপও কাজ করতে পারে। দ্রুত পরীক্ষা; আমি 'file1..file4' তৈরি করেছি এবং অনেক চেষ্টা করেছিলাম:

for i in file*;do losetup -f ~/$i;done

numchunks=3
for i in `seq 0 $numchunks`; do
        sizeinsectors=$((`ls -l file$i | awk '{print $5}'`/512))
        startsector=$(($i*$sizeinsectors))
        echo "$startsector $sizeinsectors linear /dev/loop$i 0"
done | dmsetup create joined

তারপরে, / dev / dm-0 এর মধ্যে সামগ্রী হিসাবে আপনার ফাইল সহ ভার্চুয়াল ব্লক ডিভাইস রয়েছে।

আমি এটি ভাল পরীক্ষা করিনি।

অন্য সম্পাদনা: ফাইলের আকার 512 দ্বারা সমানভাবে বিভাজ্য হতে হবে বা আপনি কিছু ডেটা হারাবেন। যদি তা হয় তবে আপনি ভাল আছেন। আমি দেখতে পাচ্ছি যে তিনি নীচেও লক্ষ করেছেন।


এই ফাইলটি একবারে পড়া ভাল ধারণা, দুর্ভাগ্যক্রমে এটি ফিফো পিছনে / এগিয়ে যাওয়ার ক্ষমতা রাখে না, তাই না?
রাশ

7
@ রশ সর্বোত্তম বিকল্পটি প্রতিটি ফাইলে একটি লুপ ডিভাইস স্থাপন করা এবং dmsetupভার্চুয়াল ব্লক ডিভাইসের মাধ্যমে তাদের একত্রিত করা (যা স্বাভাবিক সন্ধানের ক্রিয়াকলাপগুলিকে অনুমতি দেয় তবে সংযোজন বা কাটাও যায় না)। যদি প্রথম ফাইলের আকার 512 এর একাধিক না হয় তবে আপনার অসম্পূর্ণ শেষ সেক্টর এবং দ্বিতীয় ফাইল থেকে প্রথম বাইটগুলি (512 সমেত) তৃতীয় ফাইলটিতে অনুলিপি করা উচিত। দ্বিতীয় ফাইলটির জন্য লুপ ডিভাইসের --offsetতখন প্রয়োজন হবে ।
23:30 '

মার্জিত সমাধান। হউক লেজিং-কেও +1 করুন যারা প্রথম ফাইল (গুলি) এর আকার 512 এর একাধিক না হলে - সমস্যাটি সমাধানের জন্য একটি উপায় প্রস্তাব করে
অলিভিয়ার ডুলাক

9

আপনাকে এমন কিছু লিখতে হবে যা গুচ্ছগুলিতে ডেটা অনুলিপি করে যা আপনার কাছে মুক্ত স্থানের পরিমাণের চেয়ে বেশি পরিমাণে বড়। এটি এর মতো কাজ করা উচিত:

  • থেকে তথ্য একটি ব্লক পড়ুন file2( pread()সঠিক জায়গায় পড়ার আগে চেষ্টা করে ব্যবহার করে)।
  • এতে ব্লক যুক্ত করুন file1
  • fcntl(F_FREESP)এখান থেকে স্থানটি অপসারণ করতে ব্যবহার করুন file2
  • পুনরাবৃত্তি

1
আমি জানি ... তবে আমি এমন কোনওভাবেই ভাবতে পারিনি যা লিখনের কোডের সাথে জড়িত না এবং আমি যেটা লিখেছিলাম তা লেখার চেয়ে ভাল কিছু নয়। আমি আপনার শেষ থেকে শুরু করার চতুর কৌশল সম্পর্কে ভাবিনি!
সেলেদা

ইতি- আপনারও, শেষ থেকে শুরু না করে কাজ করবে না, তাই না?
হউক লেগেইন

না, এটি শুরু থেকে কাজ করে কারণ fcntl(F_FREESP)ফাইলের একটি প্রদত্ত বাইট পরিসরের সাথে যুক্ত স্থানকে মুক্ত করে (এটি এটিকে বিচ্ছিন্ন করে তোলে)।
সেলেদা

যে বেশ শান্ত. তবে এটি একটি খুব নতুন বৈশিষ্ট্য বলে মনে হচ্ছে। এটি আমার fcntlম্যান পৃষ্ঠায় উল্লেখ করা হয়নি (2012-04-15)।
হউক লেগেছে

4
@ হককিজিং এফ_ফ্রেইএসপি হ'ল সোলারিস। লিনাক্স (2.6.38 থেকে), এটি এর FALLOC_FL_PUNCH_HOLE পতাকা fallocateপ্রাপ্ত syscall। ফ্যালোকট ইউটিলিটির নতুন সংস্করণগুলির সাথে তার util-linuxএকটি ইন্টারফেস রয়েছে।
স্টাফেন চেজেলাস

0

আমি জানি আপনি যা চেয়েছিলেন তা তুলনায় এটি আরও কার্যকরী, তবে এটি আপনার সমস্যার যত্ন নেবে (এবং সামান্য টুকরো টুকরো করা বা হেডস্ক্র্যাচ সহ):

#step 1
mount /path/to/... /the/new/fs #mount a new filesystem (from NFS? or an external usb disk?)

এবং তারপর

#step 2:
cat file* > /the/new/fs/fullfile

বা, আপনি যদি মনে করেন সংকোচনের সাহায্য করবে:

#step 2 (alternate):
cat file* | gzip -c - > /the/new/fs/fullfile.gz

তারপরে (এবং কেবলমাত্র তখন), অবশেষে

#step 3:
rm file*
mv /the/new/fs/fullfile  .   #of fullfile.gz if you compressed it

দুর্ভাগ্যক্রমে বাহ্যিক ইউএসবি ডিস্কের জন্য শারীরিক অ্যাক্সেস প্রয়োজন এবং এনএফএসে অতিরিক্ত হার্ডওয়্যার প্রয়োজন এবং আমার এগুলির কিছুই নেই। যাইহোক ধন্যবাদ. =)
ভিড়ের

আমি ভেবেছিলাম এটিই সেভাবেই হবে ... রব বোসের উত্তরটি তখন আপনার সেরা বিকল্প বলে মনে হচ্ছে (কাটা-কপি করার সময় ডেটা হারাতে ঝুঁকি না দিয়ে এবং পাশাপাশি FS সীমাবদ্ধতাগুলি আঘাত না করে)
অলিভিয়ার দুলাক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.