সমস্ত ফাইল কেন সংকুচিত হয় না এবং কীভাবে সমাধানটি উন্নত করা যায়


8

আমার প্রায় 20K ফাইল সহ একটি ফোল্ডার রয়েছে। ফাইলগুলি প্যাটার্ন অনুসারে নামকরণ করা হয়েছে xy_{\d1,5}_{\d4}\.abc, যেমন xy_12345_1234.abc। আমি এই কমান্ডটি ব্যবহার করে তাদের মধ্যে প্রথম 10 কে সংক্ষেপ করতে চেয়েছিলাম:

ls | sort -n -k1.4,1.9 | head -n10000 | xargs tar -czf xy_0_10000.tar.gz

তবে ফলাফল প্রাপ্ত ফাইলটির ভিতরে প্রায় 2K ফাইল ছিল।

ls | sort -n -k1.4,1.9 | head -n10000 | wc -l তবে প্রত্যাশিত হিসাবে 10000 প্রদান করে।

আমার কাছে মনে হচ্ছে আমি এখানে কিছু বেসিক ভুল বুঝছি ...

আমি লিনাক্স পুদিনা 17.1, জিএনইউ টার্ন 1.27.1 এ zsh 5.0.2 ব্যবহার করছি

সম্পাদনা করুন:

@ আর্চামারের পরামর্শ অনুসারে কাঁটাচামচ করা খুব প্রশ্রয়জনক শোনায়, সর্বশেষতম কাঁটাচামচ ফলে ফাইলটি ওভাররাইট করে - ফাইলটিতে ফাইলগুলির 'লেজ' রয়েছে - 7773 থেকে 9999 পর্যন্ত

ফলাফল xargs --show-limit: Your environment variables take up 3973 bytes POSIX upper limit on argument length (this system): 2091131 POSIX smallest allowable upper limit on argument length (all systems): 4096 Maximum length of command we could actually use: 2087158 Size of command buffer we are actually using: 131072

প্রতিস্থাপন -cকরা -rবা -uআমার ক্ষেত্রে কাজ করে না। ত্রুটি বার্তা ছিলtar: Cannot update compressed archives

উভয় ব্যবহার করে -rএবং -uঅবৈধ এবং এর সাথে ব্যর্থ হয়tar: You may not specify more than one '-Acdtrux', '--delete' or '--test-label' option

প্রতিস্থাপন -cসঙ্গে -aপাশাপাশি অবৈধ বলে মনে হচ্ছে এবং একই সঙ্গে ব্যর্থ tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' optionsযদিও আমি বিষয়টি স্বীকার করে azfএবং Acdtruxআমাকে বিচ্ছিন্ন বলে মনে হচ্ছে।

সম্পাদনা 2:

- এটি দেখতে ভাল উপায়, আমি এখানে একটি উদাহরণও পেয়েছি ।

তবে আমি যখন চেষ্টা করি

ls | sort -n -k1.4,1.9 | head -n10000 | tar -czf xy_0_10000.tar.gz -T - আমি পাই tar: option requires an argument -- 'T'

ভাল, সম্ভবত ফাইলের নামগুলি ডলার না পৌঁছায়? তবে দেখে মনে হচ্ছে এগুলি কর, কারণ যখন আমি মৃত্যুদন্ড কার্যকর করি

ls | sort -n -k1.4,1.9 | head -n10000 | tar --null -czf xy_0_10000.tar.gz -T - আমি পাই tar: xy_0_.ab\nxy_1_...<the rest of filenames separated by literal \n>...998.ab Cannot stat: File name too long

তাহলে তারার ফাইল নাম কেন দেখছে না?


এবং আপনি যদি c এর পরিবর্তে তারার কমান্ডে চেষ্টা করেন?
অলিভিয়ার ডুলাক


1
ওপি-র ফাইলের ছদ্মবেশী নাম নেই।
আর্চেমার

@ 8 বিট্রি - পাশাপাশি শক্তিশালী শেল স্ক্রিপ্টগুলির জন্য একটি সাধারণ পরামর্শ, হ্যাঁ। তবে নিয়মিত ওয়ান-অফ অনলাইনারদের সাথে ফাইলগুলির তালিকাগুলি নিয়ে কাজ করার পরিবর্তে আপনি কী প্রস্তাব দেন?
kostja

1
@ কোস্টজা আমি ব্যবহার করব find, এতে -print0একটি নিউলাইন পরিবর্তে ডিলিমেটার হিসাবে নাল বাইট ব্যবহার করার বিকল্প রয়েছে । পতাকা sortদিয়ে যে পরিচালনা করতে পারেন -zheadদুর্ভাগ্যবশত নাল বাইট বিভেদক বুঝতে হ্যান্ডেল করে না, কিন্তু এই উত্তর একটি সলিউশন ব্যবহার হয়েছে trswap 'র জন্য \nএবং \0আগে ও পরে headtarহয়েছে --null -T -থেকে নাল সীমায়িত ফাইলের নাম পড়তে stdin
বিট্রি

উত্তর:


12

আপনি xargs সীমা আঘাত করেছেন?

xargs --show-limit

চেষ্টা করুন:

  • একটি ডামি .tgzফাইল তৈরি করুনtar czf xy_0_10000.tar.gz /hello/world
  • -czfদ্বারা প্রতিস্থাপন-Azf

যখন xarg এর সীমাটি আঘাত করে, এটি কমান্ডটি কাঁটাবে, সুতরাং আপনার আদেশটি চূড়ান্তভাবে দৌড়েছিল

  tar czf xy_0_10000.tar.gz file1 file2 .... file666
  tar czf xy_0_10000.tar.gz file667 file668 ... file1203
  tar czf xy_0_10000.tar.gz file1024 ... file2000

পূর্ববর্তী এক ট্যারে ওভারাইড হিসাবে, আপনি কেবল সর্বশেষ tar cরান পাবেন।

সম্পাদনা:

1) আনবুন্টু অনুসারে man tar, -aএবং -r সমতুল্য সংযোজন (উভয় দ্বারা) করা হয়েছে বলে মনে হচ্ছে-A, --catenate, --concatenate

2) zip(না gzip) ফাইল যুক্ত করতে ব্যবহার করা যেতে পারে, সম্ভবত একটি জিজিপ বিকল্পটি কৌশলটি করবে। (ব্যবহার করুন | xargs zip -qr xy_0_0000.zip, এটি একটি জিপ ফাইলের ফলস্বরূপ হবে, তবে .tar.gz নয়)

3) @ আরএসচেজের সমাধানটি ব্যবহার
করার জন্য একটি সঠিক উপায়ে টারের বিকল্প যুক্ত করা গুরুত্বপূর্ণ, চেষ্টা করুন

ls | sort -n -k1.4,1.9 | head -n10000 |tar -czf xy_0_10000.tar.gz -T -

যেখানে - -T -গড় বিকল্প বিকল্প -Tএবং -যুক্তি হিসাবে ব্যবহার করুন -T(আপনি ফাইলের একটি তালিকা তৈরি করতে পারতেন /tmp/foo.lst, তারপরে ব্যবহার করুন -T /tmp/foo.lst)


সি (= তৈরি / ওভাররাইট) এর পরিবর্তে কোন (= যুক্ত) এই সীমাবদ্ধতার চারপাশে কাজ করতে পারে?
অলিভিয়ার ডুলাক

@ অলিভিয়ারডুলাক ( সতর্কতা: এটি একটি বিশুদ্ধ অনুমান ) ট্যার খালি ফাইল তৈরি করতে পারে না বলে এটি সম্ভবত সমাধান হবে না। আপনি প্রথমে একটি খালি ফোল্ডার সংকোচন করতেa (add) পারেন এবং টর ফাইলটিতে ফাইলগুলি যুক্ত করতে ব্যবহার করতে পারেন। তারপরে, আপনি টারটি খুলতে এবং ফোল্ডারটি সরিয়ে ফেলতে পারেন (7zip বা কিছু ব্যবহার করে)
ইসমাইল মিগুয়েল

@ ইসমাইলমিগুয়েল: আমি নিশ্চিত যে এটি আনন্দের সাথে ফাইলটি তৈরি করবে। যদি তা না হয় তবে কেবল:touch xy_0_10000.tar.gz && { _the full command here_ ; }
অলিভিয়ার ডুলাক

1
@ অলিভিয়ারডুলাক এটি একটি অবৈধ .gzফাইল হবে।
ইসমাইল মিগুয়েল

আমি manpages.ubuntu.com/manpages/vided/en/man1/tar.1.html (15.04) থেকে যথাযথ (12.04) অবধি দেখতে পাওয়া সমস্ত ম্যানেজেজগুলিতে অ্যাপেন্ড -rকিন্তু -aঅটো-সংক্ষেপণ রয়েছে যা সমতুল্য নয়। এবং -rzকাজ করে না: zipডিরেক্টরিটি সংকুচিত না হওয়ায় একটি বিদ্যমান সংরক্ষণাগারে যুক্ত করতে পারে তবে tarসংকোচনের সাথে ডেটা সহ মেটাডেটা সংকুচিত হয়। আপনি tar -rএকটি সঙ্কুচিত সংরক্ষণাগারটিতে টুকরো টুকরো করে টুকরো টুকরো করে ফলাফলটি জিপ করতে পারেন। বা ...
ডেভ_থমপসন_0৮৮

12

দরকার নেই xargs। আপনি সরাসরি দেবে বিকল্প এটা হবে ফাইলের নামের পড়া স্ট্যান্ডার্ড ইনপুট থেকে।tar-T -

এই ক্ষেত্রে:

... | tar -T - -czf xy_0_10000.tar.gz

আমি বিকল্পটি ভুলভাবে ব্যবহার করছি বলে মনে হচ্ছে, পাইপের সাহায্যে এটি কাজ করতে পারে না। আছে চেষ্টা ...| tar Tczf xy_..., ...| tar Tcz -f xy_... ...| tar -czf xy_... -T এবং একাধিক অন্যান্য একাধিক বিন্যাসন, কিন্তু শুধুমাত্র পাচ্ছি tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options, tar: -f: Cannot stat: No such file or directoryযদি ব্যবহার -fঅন্যান্য অপশন এবং থেকে আলাদাভাবে tar: option requires an argument -- 'T'। আপনি দয়া করে একটি ব্যবহারের উদাহরণ যুক্ত করতে পারেন?
Kostja

@ কোস্টজা উদাহরণ যোগ করা হয়েছে।
rsanchez

অনেক ধন্যবাদ, আরএসচেঞ্জ। বিকল্প তালিকার -T -শেষে বৈকল্পিক কেন tarকাজ করে নি তা নিশ্চিত নয়, তবে আপনার উদাহরণটি কার্যকর হয়েছিল। দুর্ভাগ্যক্রমে, আমার প্রশ্নের আসলে দুটি অংশ ছিল - ত্রুটির উত্স এবং একটি সম্ভাব্য উন্নতির। আপনি যখন দ্বিতীয়টিকে আর্শিয়ার করেছিলেন, তখন আরচেমার পূর্বের দিক থেকে দক্ষতা অর্জন করেছিলেন এবং তারপরের অংশটি সঠিক ছিল। আমি নিশ্চিত নই যে আপনার উত্তরগুলির মধ্যে কোনটি গ্রহণ করতে হবে কারণ তারা উভয়ই স্পষ্টত সহায়ক ছিল helpful
kostja

1

আমি zsh সমাধান সহ আরও দুটি উত্তর পরিপূরক করতে চাই , যা না ls কে পার্স করে , না xargs প্রয়োজন । তবে, আমি এখনই নিশ্চিত নই, যদি এটি কমান্ড লাইনের দৈর্ঘ্যের সীমাবদ্ধতায়ও ভোগে।

  1. কোনও ফাংশন সংজ্ঞায়িত করুন যা আপনার পছন্দসই বাছাইকরণ কীটি সংশোধন করে জেনারেট করে $REPLY

    sortkey() { REPLY=${REPLY[4,9]} }

    এটি আপনার সমতুল্য sort -n -k1.4,1.9

  2. $filesউপরের ফাংশনটির সাথে বাছাই করা ফাইলের নাম সহ একটি অ্যারে তৈরি করুন :

    files=(*(o+sortkey))

    এটি সমান ls | sort -n -k1.4,1.9

  3. এর সাথে প্রথম 10,000 ফাইল ফেরত দিন

    ${files[0,9999]}

    এটি সমান ls | sort -n -k1.4,1.9 | head -n10000

সুতরাং, এই সমস্ত কিছুতে কৌশলটি করা উচিত:

sortkey() { REPLY=${REPLY[4,9]} }
files=(*(o+sortkey))
tar -czf xy_0_10000.tar.gz ${files[0,9999]}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.