LS এর পক্ষে যুক্তি তালিকা খুব দীর্ঘ


48

ls *.txt | wc -lঅনেকগুলি ফাইল রয়েছে এমন কোনও ডিরেক্টরিতে চেষ্টা করার সময় আমি নিম্নলিখিত ত্রুটিটি পেয়েছি :

-bash: /bin/ls: Argument list too long

এই "তর্ক তালিকার" এর প্রান্তিকতা কি ডিস্ট্রো বা কম্পিউটারের অনুকূলে নির্ভর করে? সাধারণত, আমি এ জাতীয় বড় ফলাফলের ফলাফলটি অন্য কয়েকটি কমান্ডের ( wc -lযেমন উদাহরণস্বরূপ) পাইপ করতাম , সুতরাং আমি টার্মিনালের সীমা নিয়ে উদ্বিগ্ন নই।


6
এটিকে পার্সিংয়ের lsআউটপুট হিসাবে বিবেচনা করা হয় , যা একটি খারাপ ধারণা, সুতরাং এটি এড়ানো ভাল avoid গণনা করার জন্য দেখুন ডিরেক্টরিতে ফাইল সংখ্যা গণনা করার সেরা উপায় কী? , একটি কৌশলপূর্ণ কাজের জন্য দেখুন কেন লুপের জন্য "তর্ক খুব দীর্ঘ" ত্রুটি বাড়ে না?
manatwork

@ মান্যাটওয়ার্ক হ্যাঁ, আমি এই প্রশ্নগুলিও দেখেছি। আরও সাধারণ ফ্যাশনে কোনও আদেশ থেকে একটি দীর্ঘ আউটপুট পুনঃনির্দেশ করার আরও ভাল উপায় সম্পর্কে ভাবছি।

আপনি সবচেয়ে UNIX ভিত্তিক সিস্টেমে সীমা পেতে ARG_MAX getconf ব্যবহার করতে পারেন
Prasanth

উত্তর:


49

তোমার ত্রুটি বার্তা আর্গুমেন্ট তালিকার অত্যন্ত দীর্ঘ থেকে আসে * এর ls *.txt

এই সীমাগুলি বাইনারি প্রোগ্রাম এবং আপনার কার্নেল উভয়েরই জন্য সুরক্ষা। আপনি এই পৃষ্ঠায় এটি সম্পর্কে আরও তথ্য এবং এটি কীভাবে ব্যবহৃত এবং গণনা করা হবে তা দেখতে পাবেন ।

পাইপের আকারের মতো সীমা নেই। সুতরাং আপনি কেবল এই আদেশটি জারি করতে পারেন:

find -type f -name '*.txt'  | wc -l

এনবি: আধুনিক লিনাক্সে, ফাইলের নামগুলিতে অদ্ভুত অক্ষরগুলি (নতুন লাইনের মতো) lsবা এর মতো সরঞ্জামগুলি সহ পালানো হবে findতবে তবুও * থেকে প্রদর্শিত হবে । আপনি যদি পুরানো ইউনিক্সে থাকেন তবে আপনার এই কমান্ডটি লাগবে

find -type f -name '*.txt' -exec echo \;  | wc -l

এনবি 2: আমি ভাবছিলাম যে কেউ কীভাবে একটি নতুন লাইন দিয়ে একটি ফাইল তৈরি করতে পারে তার নামে। একবার আপনি কৌশলটি জানলে এটি এতটা কঠিন নয়:

touch "hello
world"

1
আমি যখন এগুলিতে নতুন লাইনের সাথে ফাইলের নাম রাখি তখন ক্ষেত্রে কাজ করার জন্য এটি সামান্য পরিবর্তিত করেছি। আপনি -maxdepth 1যদি সাব-ডিরেক্টরিতে ফাইল গণনা করতে চান না তবে আপনি একটি যুক্ত করতেও পারেন You
শন জে গফ

আপনি প্রয়োজন হবে না -exec echo \;
মাইকেল

@ শনজ.গফ আমি এটি পরীক্ষা করেছি। এটি গনুহ বর্তমান সংস্করণে `echo` কোন প্রয়োজন নেই
Coren

@ কোরেন @ মাইকেল - প্রত্যেকেরই জিএনইউ নেই findfindOS এ X এবং, busybox ভিত্তিক সিস্টেমে, আর আমি কোন বাসদ-ভিত্তিক সিস্টেমের অনুমান হবে গণনা সঙ্গে এটা একটি newline, যা জগাখিচুড়ি would সঙ্গে ফাইলের নাম দেখায়।
শন জে গফ

তাই না? wc -lনতুন লাইন গণনা করা হয়। সুতরাং আমরা এটি নতুন লাইনে আছে চান
মাইকেল

11

এটি আপনার লিনাক্স কার্নেলের সংস্করণে নির্ভর করে।

আপনার সিস্টেমে চালিয়ে যাওয়ার সীমাটি দেখতে সক্ষম হওয়া উচিত

getconf ARG_MAX

শেল দ্বারা প্রসারিত হওয়ার পরে একটি কমান্ড লাইনের সর্বাধিক সংখ্যক বাইট বলতে পারে।

লিনাক্স <2.6.23 এ, সীমাটি সাধারণত 128 কেবি হয়।

লিনাক্স> = 2.6.25 এ সীমাটি হয় 128 কেবি বা আপনার স্ট্যাকের আকারের (1/4 ulimit -s) যেকোন বৃহত্তর is

দেখুন execve (2) man পৃষ্ঠা সব বিস্তারিত জানার জন্য।


দুর্ভাগ্যক্রমে, পাইপিং ls *.txtসমস্যাটি ঠিক করতে যাচ্ছে না, কারণ সীমাটি অপারেটিং সিস্টেমে রয়েছে, শেল নয়।

শেলটি প্রসারিত করে *.txt, তারপরে কল করার চেষ্টা করে

exec("ls", "a.txt", "b.txt", ...)

এবং আপনার কাছে এতগুলি ফাইলের মিল রয়েছে *.txtযে আপনি 128 কেবি সীমা ছাড়িয়ে গেছেন।

আপনাকে এরকম কিছু করতে হবে

find . -maxdepth 1 -name "*.txt" | wc -l

পরিবর্তে.

(এবং নতুন লাইনে থাকা ফাইলের নাম সম্পর্কে শন জে গফের মন্তব্যগুলি নীচে দেখুন))


একটি উত্তর upvote করতে সক্ষম না জন্য দুঃখিত। আরও খ্যাতি দরকার। :( আপনাকে ধন্যবাদ !!

আপনি শেষ লাইনে কী .এবং এর -maxdepth 1অর্থ কী তা ব্যাখ্যা করতে পারেন ? ধন্যবাদ! : ডি
গিলহর্মি সালোমে

2
@ গিলহেরেমসালোম-এর .অর্থ বর্তমান ডিরেক্টরি -maxdepth 1means এটি একই ফাইলগুলির সাথে মিলে যাওয়ার উদ্দেশ্যে করা হয়েছিল *.txt
মাইকেল

9

আরেকটি কাজ

ls | grep -c '\.txt$'

যদিও lsউত্পাদনের চেয়ে বেশি আউটপুট ls *.txtউত্পাদন করে (বা উত্পাদন করার চেষ্টা করে) এটি "যুক্তি খুব দীর্ঘ" সমস্যার মধ্যে চলে না কারণ আপনি কোনও যুক্তিই পাস করেন না ls। নোট যা grepকোনও ফাইলের মিলের প্যাটার্নের চেয়ে নিয়মিত প্রকাশ করে।

আপনি ব্যবহার করতে পারেন:

ls -U | grep -c '\.txt$'

( lsএই সংস্করণটিকে সমর্থন করে আপনার সংস্করণটিকে সমর্থন করে)। এটি lsতার আউটপুটটি বাছাই না করতে বলে , যা সময় এবং মেমরি উভয়ই সাশ্রয় করতে পারে - এবং এই ক্ষেত্রে ক্রমের কোনও গুরুত্ব নেই কারণ আপনি কেবল ফাইলগুলি গণনা করছেন। আউটপুটটি বাছাই করতে ব্যয় করা সংস্থানগুলি সাধারণত তাৎপর্যপূর্ণ নয়, তবে এই ক্ষেত্রে আমরা ইতিমধ্যে জানি যে আপনার কাছে খুব বেশি সংখ্যক *.txtফাইল রয়েছে।

এবং আপনার ফাইলগুলি পুনর্গঠিত করার কথা বিবেচনা করা উচিত যাতে আপনার একক ডিরেক্টরিতে এত বেশি না থাকে। এটি সম্ভব এবং নাও সম্ভব।


1

MAX_ARG_PAGES কার্নেল প্যারামিটার হিসাবে উপস্থিত হয়। এই সীমাটি সম্বোধনের জন্য একটি সাধারণ সমন্বয় ব্যবহার করা findএবং xargsএটি তবে আমি নিশ্চিত নই যে এটির জন্য এটি কাজ করবে wc

find . -name \*\.txtকোনও ফাইলের আউটপুট পাইপিং করা এবং সেই ফাইলের লাইনগুলি গণনা করা একটি কর্মফল হিসাবে পরিবেশন করা উচিত।


আপনি lsআউটপুট দিয়ে কিছু করতে পারেন , এটি সমাধান করবে না। যতক্ষণ * * টেক্সট ওয়াইল্ডকার্ড সীমা ছাড়িয়ে প্রসারিত হয় ততক্ষণ lsকোনও আউটপুট শুরু করা ও উত্পন্ন করার আগে ব্যর্থ হবে ।
manatwork

সত্য, আমি আমার উত্তর আপডেট করেছি।
ব্রাম

উত্তম. তবে এটির জন্য lsআপনার প্রতিস্থাপনের জন্য -maxdepth 1সাব-ডিরেক্টরিগুলি পুনরাবৃত্তভাবে স্ক্যান করা এড়াতে নির্দিষ্ট করা উচিত ।
manatwork

একটি উত্তর upvote করতে সক্ষম না জন্য দুঃখিত। আরও খ্যাতি দরকার। :(

0

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

ls | grep jpg | <something>

আমি jpgs এর 90,000 দীর্ঘ তালিকা পেয়েছিলাম এবং টাইমলেস উত্পন্ন করার জন্য তাদের অ্যাঙ্কনভিতে পাইপ করছিলাম।

আমি আগে ls * .jpg ব্যবহার করছিলাম আমি এই সমস্যার আগে চালানোর আগে avconv।

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