কোনও ফাইলের শুরু থেকে বাইটস সরিয়ে ফেলার সেরা উপায়?


61

আজ আমাকে একটি 800 এমবি মিশ্র পাঠ্য / বাইনারি ফাইল থেকে প্রথম 1131 বাইটগুলি সরিয়ে ফেলতে হবে, একটি ফিল্টারযুক্ত সাবভারশন ডাম্প আমি একটি নতুন সংগ্রহস্থলের জন্য হ্যাক করছি। এটি করার সর্বোত্তম উপায় কী?

শুরু করার জন্য আমি চেষ্টা করেছি

dd bs=1 skip=1131 if=filtered.dump of=trimmed.dump

তবে এড়িয়ে যাওয়ার পরে এই ফাইলটির বাকী অংশগুলি একবারে বাইট, অর্থাৎ খুব ধীরে ধীরে অনুলিপি করে। শেষ পর্যন্ত আমি পরিশ্রম করেছি আমার ৪০৫ বাইটের এটি প্রয়োজন যাতে আমি এড়িয়ে যেতে পারব এমন 512 টির তিনটি ব্লককে গোল করতে পারি

dd if=/dev/zero of=405zeros bs=1 count=405
cat 405zeros filtered.dump | dd bs=512 skip=3 of=trimmed.dump

যা মোটামুটি দ্রুত সম্পন্ন হয়েছে তবে অবশ্যই একটি সহজ / আরও ভাল উপায় থাকতে পারে? আমি ভুলে গিয়েছিলাম কি অন্য কোন সরঞ্জাম আছে? ধন্যবাদ!


ddকাজের জন্য সঠিক সরঞ্জাম - দেখে মনে হচ্ছে আপনি নিজের সমস্যার সুন্দর, মার্জিত সমাধান নিয়ে এসেছেন।
জাস্টিন ইথিয়ার

উত্তর:


62

আপনি বিএস পরিবর্তন করতে পারেন এবং বিকল্পগুলি এড়িয়ে যেতে পারেন:

dd bs=1131 skip=1 if=filtered.dump of=trimmed.dump

এভাবে অপারেশনটি বৃহত্তর ব্লক থেকে উপকৃত হতে পারে।

অন্যথায়, আপনি লেজ দিয়ে চেষ্টা করতে পারেন (যদিও এটি বাইনারি ফাইলগুলির সাথে এটি ব্যবহার করা নিরাপদ নয়):

tail -c +1132 filtered.dump >trimmed.dump

অবশেষে, আপনি এই জাতীয় কিছু লিখতে 3 ডি উদাহরণ ব্যবহার করতে পারেন:

dd if=filtered.dump bs=512k | { dd bs=1131 count=1 of=/dev/null; dd bs=512k of=trimmed.dump; }

যেখানে প্রথম ডিডি তার স্ট্যান্ডার্ড আউটপুট ফিল্টার করে তোলে। দ্বিতীয়টি কেবল 1131 বাইট পড়ে সেগুলি ফেলে দেয়; তারপরে, শেষটি তার স্ট্যান্ডার্ড ইনপুট থেকে ফিল্টারডডাম্পের বাকী বাইটগুলি পড়ে এবং ট্রিমড.ডম্প এ লিখুন।


6
ধন্যবাদ! আমি জানতাম না যে পাইপযুক্ত ইনপুটটি এর মতো দ্বিতীয় প্রক্রিয়াতে নিয়ে গেছে - এটি খুব ঝরঝরে। আমি bs=1131 skip=1যদিও ভাবিনি বলে বিশ্বাস করতে পারি না : - /
রুপ

2
শেল ইউটিলিটিগুলির বেশিরভাগ আধুনিক প্রয়োগগুলি বাইনারি ফাইলগুলির সাথে সঠিকভাবে কাজ করে (যেমন তাদের নাল অক্ষরগুলির সাথে কোনও সমস্যা নেই এবং ফাইলটির শেষে কোনও অতিরিক্ত নতুন লাইন প্রবেশ করাবে না)। অবশ্যই জিএনইউ এবং * বিএসডি বাস্তবায়ন নিরাপদ।
গিলস

17

কখন যুক্ত skip_bytesহয়েছিল তা নিশ্চিত নয় , তবে আপনার কাছে থাকা প্রথম 11 বাইটগুলি এড়িয়ে যেতে:

# echo {123456789}-abcdefgh- | 
                              dd bs=4096 skip=11 iflag=skip_bytes
-abcdefgh-
0+1 records in
0+1 records out
11 bytes (11 B) copied, 6.963e-05 s, 158 kB/s

যেখানে iflag=skip_bytesডিডিকে skipব্লকের পরিবর্তে বাইট হিসাবে বিকল্পটির মানটি ব্যাখ্যা করতে বলে , এটি সোজা করে।


অবশ্যই বড় ফাইলগুলির জন্য একটি গতির সুবিধা এবং অল্প পরিমাণে ডেটা সরানো হবে।
sstn

এটি সর্বোত্তম উত্তর, যেহেতু এটি প্রতিটি ব্লকের আকারের জন্য কাজ করে যেমনiflag=skip_bytes skip=1234 bs=1M
ফায়ারস্কি

15

আপনি একটি সাব-শেল এবং এর ddমতো দুটি কল ব্যবহার করতে পারেন :

$ ( dd bs=1131 count=1 of=dev_null && dd bs=4K of=out.mp3 ) < 100827_MR029_LobbyControl.mp3
1+0 records in
1+0 records out
1131 bytes (1.1 kB) copied, 7.9691e-05 s, 14.2 MB/s
22433+1 records in
22433+1 records out
91886130 bytes (92 MB) copied, 0.329823 s, 279 MB/s
$ ls -l *
-rw------- 1 max users 91887261 2011-02-03 22:59 100827_MR029_LobbyControl.mp3
-rw-r--r-- 1 max users     1131 2011-02-03 23:04 dev_null
-rw-r--r-- 1 max users 91886130 2011-02-03 23:04 out.mp3
$ cat dev_null out.mp3 > orig
$ cmp 100827_MR029_LobbyControl.mp3 orig

1
ধন্যবাদ - আমি জানি না পাইপ ইনপুটটি এর মতো দ্বিতীয় প্রক্রিয়া অব্যাহত রাখে, আমি অনুমান করি এটি সাব শেল? আমি অবশ্যই মনে রাখব! আমি মার্কোটিকে টিক দিয়েছি কারণ তিনি এখানে প্রথম এসেছিলেন তবে +1 এবং উত্তরের জন্য ধন্যবাদ!
রুপ

1
@ রুপ, হ্যাঁ, উপ-শেল - প্রথম বন্ধনীগুলির মাধ্যমে তৈরি - একটি স্টিডিন ফাইল বিবরণী সরবরাহ করে এবং উভয় ডিডি কলগুলি ক্রমাগত এটি থেকে ইনপুট গ্রাস করে। হ্যাঁ - মার্কো আমাকে 29 সেকেন্ডের মধ্যে পরাজিত করেছে :)
ম্যাক্সচলেপজিগ

6

যদি ফাইল সিস্টেম এবং লিনাক্স কার্নেল এটি সমর্থন করে তবে আপনি fallocateপরিবর্তনগুলি স্থানান্তর করতে চাইলে চেষ্টা করতে পারেন: সর্বোত্তম ক্ষেত্রে কোনও তথ্য আইও নেই:

$ fallocate <magic> -o 0 -l 1131 inplace.dump

যেখানে <magic>ফাইল সিস্টেম, লিনাক্স সংস্করণ এবং ফাইলের ধরণের উপর নির্ভর করে ( FALLOC_FL_COLLAPSE_RANGEবা FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZEঅভ্যন্তরীণভাবে ব্যবহৃত হতে পারে )।


1
এটি আমার পছন্দের পদ্ধতি, তবে এটি একটি ধারকটিতে চালানোর সমস্যা রয়েছে। stackoverflow.com/questions/31155591/…
michaelcurry

3

আপনার ব্যবহার করা উচিত count=0- এটি lseek()সম্ভব যখনই সম্ভব।

এটার মত:

{  dd bs=1131 skip=1 count=0; cat; } <filtered.dump >trimmed.dump

ddহবে lseek()অফসেট একটি 1131 বাইট ইনপুট ফাইল বর্ণনাকারী, এবং তারপর catশুধু কপি হবে যাই হোক না কেন আউটপুট রয়ে যায়।


2

তা সত্ত্বেও (ব্যবহার না করেই একটি ফাইল থেকে নেতৃস্থানীয় বাইট মুছে ফেলার জন্য অন্য উপায় ddএ সব) ব্যবহার করতে হয় xxdএবং sedবা tailযথাক্রমে।

bytes=$((1131*2))

xxd -p -c 256 filtered.dump | tr -d '\n' | sed "s/^.\{0,${bytes}\}//" | xxd -r -p > trimmed.dump

bytes=$((bytes + 1)) 
xxd -p -c 256 filtered.dump | tr -d '\n' | tail -c +${bytes} | xxd -r -p > trimmed.dump

এটি পরিষ্কার, তবে আমি মনে করি যে আমি ফাইলটি হেক্স এবং এ থেকে রূপান্তর না করে কেবল বাইনারিতে কাজ করা পছন্দ করি।
রূপ

2

@ ম্যাক্সচলেপজিগ একটি অনলাইন লাইনার চাইছেন। এখানে পার্ল এক। এটি 2 টি যুক্তি লাগে: বাইট এবং দৈর্ঘ্য থেকে। ইনপুট ফাইল অবশ্যই '<' দ্বারা দেওয়া উচিত এবং আউটপুট স্টাডআউটে হবে:

perl -e 'sysseek(STDIN,shift,0) || die; $left = shift;
     while($read = sysread(STDIN,$buf, ($left > 32768 ? 32768 : $left))){
        $left -= $read; syswrite(STDOUT,$buf);
     }' 12345678901 19876543212 < bigfile > outfile

দৈর্ঘ্য যদি ফাইলের চেয়ে বড় হয় তবে বাকী ফাইলটি অনুলিপি করা হবে।

আমার সিস্টেমে এটি 3.5 গিগাবাইট / গুলি সরবরাহ করে।


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

@ রুপ আলাস, তবে নেই। আপনি ভুলে যাবেন বলে মনে হচ্ছে এটি ddসম্পূর্ণ পড়ার গ্যারান্টি দেয় না। চেষ্টা করুন: হ্যাঁ | dd বিএস = 1024 কে গণনা = 10 | wc- unix.stackexchange.com/questions/17295/...
ওলে Tange থেকে

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