নির্দিষ্ট ডিরেক্টরিতে কতগুলি ফাইল এবং ডিরেক্টরি রয়েছে তা খুঁজে পাওয়ার জন্য ডাব্লুসি এবং পাইপিং কীভাবে ব্যবহার করবেন?


10

wcডিরেক্টরিতে কতগুলি ফাইল বা ডিরেক্টরি রয়েছে তা গণনা করতে আমি কীভাবে ওয়ার্ড কাউন্টার ( ) এবং পাইপিং ব্যবহার করতে পারি /usr/bin?


এই হোমওয়ার্ক ?? সাহায্যের জন্য জিজ্ঞাসা করা ঠিক আছে, ঠিক যদি এটি হয় তবে এটি সনাক্ত করুন।
slm

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

ls / বিন / usr / বিন | সাজানো | uniq | wc -
নগদ

NP। সাহায্যের জন্য জিজ্ঞাসা করা এটি পুরোপুরি ঠিক! কেবল এটির লেবেল করুন যাতে লোকেরা জানতে পারেন, ইউনিক্সের সূক্ষ্ম পয়েন্টগুলি শেখার চেষ্টা করা লোকদের এখানে সহায়তা করার জন্য এখানকার প্রত্যেকেই সাধারণত খুশি হন।
slm

উত্তর:


13

একটি পদ্ধতির lsআমাদের ফাইলগুলির একটি তালিকা দেওয়ার জন্য ব্যবহার করা হবে , তবে আমরা এই তালিকাটি প্রতি লাইনে কেবল 1 টি ফাইল বা ডিরেক্টরি দেখানোর নিশ্চয়তা দিতে চাই। -1সুইচ আমাদের জন্য এই কাজ করবে।

$ ls -1
dir1
dir2
dir3
fileA
fileB
fileC

উদাহরণ

একটি খালি ডিরেক্টরিতে উপরের নমুনা ডেটা তৈরি করুন।

$ mkdir dir{1..3}
$ touch file{A..C}

এটি পরীক্ষা করুন:

$ ls
dir1  dir2  dir3  fileA  fileB  fileC

এখন গণনা করতে আপনি wc -lলাইন সংখ্যা গণনা করতে পারেন , যা ls -1আউটপুটে কোনও ফাইল বা ডিরেক্টরিতে মিল রয়েছে।

$ ls -1 | wc -l
6

(তবে লক্ষ্য করুন যে এতে লুকানো ফাইলগুলি অন্তর্ভুক্ত নেই)

ফাইল বা ডিরেক্টরি গণনা, কেবল একসাথে নয়

ফাইল বা ডিরেক্টরি গণনা করার জন্য আপনার কৌশলটি কিছুটা পরিবর্তন করতে হবে। এই ক্ষেত্রে আমি ব্যবহার করব ls -lযেহেতু এটি দেখায় যে একটি ডিরেক্টরি কী এবং এএ ফাইলটি কী।

উদাহরণ

$ ls -l
total 12
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir1
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir2
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir3
-rw-rw-r-- 1 saml saml    0 Nov 16 09:49 fileA
-rw-rw-r-- 1 saml saml    0 Nov 16 09:49 fileB
-rw-rw-r-- 1 saml saml    0 Nov 16 09:49 fileC

তারপরে আমরা grepডিরেক্টরিগুলি বা না-ডিরেক্টরিগুলি ফিল্টার আউট ব্যবহার করতে পারি :

# directories
$ ls -l | grep "^d"
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir1
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir2
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir3

# regular files
$ ls -l | grep "^-"
-rw-rw-r-- 1 saml saml    0 Nov 16 09:49 fileA
-rw-rw-r-- 1 saml saml    0 Nov 16 09:49 fileB
-rw-rw-r-- 1 saml saml    0 Nov 16 09:49 fileC

উপরেরটি wc -lগণনা করতে এখন কেবল আবার ব্যবহার করুন :

# directories
$ ls -l | grep "^d" | wc -l
3

# regular files
$ ls -l | grep "^-" | wc -l
3

যদিও আপনি wcপুরোপুরি এড়াতে পারেন এবং grepএর -cবিকল্পটি ব্যবহার করতে পারেন :

$ ls -l | grep -c '^d'

(আবারও, লুকানো ফাইলগুলি অন্তর্ভুক্ত নয়। নোট করুন যে ডিরেক্টরি এবং নিয়মিত দুটি ধরণের ফাইল named আরও অনেক রয়েছে নামকৃত পাইপ, প্রতীকী লিঙ্ক, ডিভাইস, সকেট ...)।

recursion

আপনার যদি ফাইল এবং ডিরেক্টরিগুলি পুনরাবৃত্তির অধীনে সন্ধান /usr/binকরতে হয় তবে আপনি সম্ভবত কৌশলগুলি সম্পূর্ণরূপে পরিবর্তন করতে এবং ডাকা অন্য সরঞ্জামটি ব্যবহার করতে চাইবেন find

উদাহরণ

$ find /usr/bin | wc -l
4632

(যদিও উপরে /usr/binনিজেই গণিতে অন্তর্ভুক্ত রয়েছে)

আমি উপরে যে একই কৌশলগুলি ব্যবহার করেছি তেমন lsকিছু করার জন্য ব্যবহার করা যেতে পারে lsতবে আউটপুটটি বিশ্লেষণ করার জন্য সাধারণত কোনও ভাল সরঞ্জাম নয়। findঅন্যদিকে এটি এর জন্য নির্মিত হয়েছিল এবং ফাইল বা ডিরেক্টরিগুলি হয় সন্ধানের জন্য সুইচ সরবরাহ করে।

# find files
$ find /usr/bin -type f

# find directories
$ find /usr/bin -type d

(দ্রষ্টব্য যে এবার findলুকানো ফাইলগুলি ( .এবং বাদে ..) অন্তর্ভুক্ত রয়েছে)।

নতুন লাইন?

ফাইলের নাম বা ডিরেক্টরির নাম তৈরি করার সময় কেন একটি নতুন লাইন চরিত্রটি আইনী চরিত্র হিসাবে ব্যবহার করা যায় তা আমি কখনই বুঝতে পারি নি। সুতরাং উপরে উল্লিখিত পদ্ধতিগুলি ব্যবহার করে wcএবং lsএগুলির সাথে বিতর্ক করবে না, তাই সেটিকে মনে রেখেই এটি ব্যবহার করুন।

উদাহরণ

নতুন লাইনগুলি সহ একটি ডিরেক্টরি এবং ফাইলের নাম তৈরি করুন।

$ mkdir $'dir4\n5'
$ touch $'fileD\nE'

ls এগুলি সঠিকভাবে দেখায়:

$ ls -1
dir1
dir2
dir3
dir4?5
fileA
fileB
fileC
fileD?E

কিন্তু wcডিরেক্টরিগুলি এবং ফাইলগুলিতে গণনা করে যেগুলিতে একটি নয়, 2 টি আইটেম হিসাবে নিউলাইন রয়েছে।

$ ls -1 | wc -l
10

এটি পেতে একটি পদ্ধতি, যদি GNU বাস্তবায়নটি ব্যবহার করে তা findহ'ল findপ্রতিটি ফাইলের জায়গায় এটি অন্য যে কোনও কিছু মুদ্রণ করার ক্ষমতা ব্যবহার করে এবং তার পরিবর্তে সেগুলি গণনা করে।

উদাহরণ

$ find . -printf . | wc -c
9

এখানে আমরা বর্তমান ডিরেক্টরিতে (ব্যতীত ..) সমস্ত কিছু সন্ধান করছি এবং .প্রত্যেকটির জন্য একটি বিন্দু ( ) প্রিন্ট করছি এবং তারপরে wcলাইনের পরিবর্তে বাইটগুলি গণনা করার ক্ষমতা ব্যবহার করে বিন্দুগুলি গণনা করছি wc -c,।

তথ্যসূত্র


ফাইলগুলিতে /usr/binসমস্ত ভাল ফর্ম্যাট করা হতে চলেছে (এবং এর মধ্যে ফাঁকা স্থানও থাকবে না, প্রযুক্তিগতভাবে আপনি এমনকি ঠিক রাখতে পারেন echo * | wc -w) তবে এটি লক্ষ্য করার মতো বিষয় যে এইগুলি সমস্তই নতুনলাইনযুক্ত ফাইল নামগুলিতে বিভক্ত হবে।
অশুভ

@ ইভিলসপ - না আমি বিশ্বাস করি না ls -lবা ls -1বি / সি ভেঙে ফেলবে আমরা লাইন গণনা করছি, শব্দ নয়! findবিরতি হতে পারে, কিন্তু আবার, আমরা লাইন গণনা করছি শব্দ।
slm

আমি কি মানে হয় যে এই ইচ্ছার বিরতি যদি ফাইল থাকতে (আমি মনে করি, আমি এই মুহূর্তে তাই আমি করতে পারবেন পরীক্ষা উইন্ডোজ উপর আছি) নতুন লাইন । সুতরাং আপনার touch $'foo\nbar'খালি কমান্ডগুলির একটি অনুসরণ করে একটি ফাঁকা ডিরেক্টরিতে (বলুন ls -1 | wc -l) একের পরিবর্তে দুটি ফাইলের প্রতিবেদন করবে - কারণ যে কোনও ফাইলটি দুটি লাইন হিসাবে wcসম্পর্কিত। যদি না lsঅন্য কিছু অক্ষর (আমি মনে করি না এটা আছে, কিন্তু আবার আমি এই মুহূর্তে পরীক্ষা করার জন্য একটি অবস্থানে নই) এর সাথে প্রতিস্থাপন নতুন লাইন।
অরিসুপ

@ ইভিলসপ - সঠিক, নিউলাইন চর আইনী চর। ফাইলের নামের জন্য এবং পদ্ধতিগুলি সঠিকভাবে সেই জাতীয় ফাইলের নামগুলির সাথে লড়াই করতে সক্ষম হবে না।
slm

@ স্টাফেনচাজেলাস - wc -cপিরিয়ড গণনা করার সময় একটি বিষয়?
slm

5

আপনি যদি জিএনইউ দিয়ে কিছু ধরণের অধীনে প্রতিটি ধরণের ফাইলের সংখ্যার বিরতি পেতে চান তবে আপনি এটি findকরতে পারেন:

find /some/dir/. ! -name . -printf '%y\n' | sort | uniq -c | sed '
  s/f/regular files/;t
  s/d/directories/;t
  s/l/symbolic links/;t
  s/s/Unix domain sockets/;t
  s/b/block devices/;t
  s/c/character devices/;t
  s/p/FIFOs/;t
  s/D/Doors/;t
  s/n/network special files/;t
  s/.$/others (&)/'

উপর /usr/binআমার সিস্টেমে, যে দেয়:

   3727 regular files
    710 symbolic links

চালু /dev:

     83 block devices
    203 character devices
     31 directories
    426 symbolic links
      1 FIFOs
      1 Unix domain sockets

সিমলিংকের জন্য, যদি আপনি তাদের পরিবর্তে ফাইলটি যে ধরণের ফাইলের দিকে ইঙ্গিত করেন তবে তা যদি আপনি এটি গণনা করেন তবে আপনি symbolic linksএটিকে পরিবর্তন করতে পারেন:

find /some/dir/. ! -name . -printf '%Y\n' | sort | uniq -c | sed '
  s/f/regular files/;t
  s/d/directories/;t
  s/N/broken symbolic links/;t
  s/s/Unix domain sockets/;t
  s/b/block devices/;t
  s/c/character devices/;t
  s/p/FIFOs/;t
  s/D/Doors/;t
  s/n/network special files/;t
  s/.$/others (&)/'

যা এখন আমার জন্য দেয় /usr/bin:

      1 directories
   4434 regular files
      2 broken symbolic links

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

যারা গণনা .এবং কেউ ..। আপনি যদি এগুলি অন্তর্ভুক্ত করতে চান (কেন আপনি করবেন?), findতারা প্রতিটি ডিরেক্টরিতে উপস্থিত রয়েছে বলে ধরে নেওয়া এবং পদ্ধতিগতভাবে তাদের গণনা ছাড়া আর কোনও উপায় নেই :

find /some/dir/. -printf '%y\n' \( -name . -printf 'd\n' -o \
  -type d -printf 'd\nd\n' \)  | sort | uniq -c | sed '
  s/f/regular files/;t
  s/d/directories/;t
  s/l/symbolic links/;t
  s/s/Unix domain sockets/;t
  s/b/block devices/;t
  s/c/character devices/;t
  s/p/FIFOs/;t
  s/D/Doors/;t
  s/n/network special files/;t
  s/.$/others (&)/'

যা আমার উপর দেয় /usr/bin:

      2 directories
   3727 regular files
    710 symbolic links

আপনার যদি জিএনইউতে অ্যাক্সেস না থাকে তবে আপনি findপ্রথমটি আবার লিখতে পারেন:

find /some/dir/. ! -name . \( \
  -type f -exec printf '%.0sregular files\n' {} + -o \
  -type d -exec printf '%.0sdirectories\n' {} + -o \
  -type l -exec printf '%.0ssymbolic links\n' {} + -o \
  -type s -exec printf '%.0sUnix domain sockets\n' {} + -o \
  -type b -exec printf '%.0sblock devices\n' {} + -o \
  -type c -exec printf '%.0scharacter devices\n' {} + -o \
  -type p -exec printf '%.0sFIFOs\n' {} + -o \
  -exec printf '%.0sothers\n' {} + \) | sort | uniq -c

এখন, কঠোরভাবে বলতে গেলে, আমরা ফাইলগুলি নয় বরং ডিরেক্টরি এন্ট্রি গণনা করছি । /usr/binসাধারণত কোনও ডিরেক্টরিতে বেশ কয়েকটি এন্ট্রি থাকে যা একই ফাইলটিতে নির্দেশ করে। উদাহরণস্বরূপ, এখানে আমার কাছে রয়েছে:

$ ls -lid /usr/bin/{nvi,nview,nex}
672252 -rwxr-xr-x 3 root root 434616 May 25 07:40 /usr/bin/nex
672252 -rwxr-xr-x 3 root root 434616 May 25 07:40 /usr/bin/nvi
672252 -rwxr-xr-x 3 root root 434616 May 25 07:40 /usr/bin/nview

এগুলি একই ডিরেক্টরিতে 3 ডিরেক্টরি এন্ট্রি (ওরফে ফাইলের নাম ওরফে হার্ড লিঙ্ক) (ইনড সহ 672252 directory ডিরেক্টরি এন্ট্রিগুলির পরিবর্তে এবং জিএনইউ findএবং জিএনইউ সহ ফাইলগুলি uniqউপেক্ষা করা (উপেক্ষা করা .এবং ..যে কোনও উপায়ে অন্য ডিরেক্টরিগুলির হার্ড লিঙ্কগুলি রয়েছে এমন ফাইলগুলি):

find /some/dir/. ! -name . -printf '%y\t%D:%i\n' |
  sort -u |
  cut -f1 |
  uniq -c |
  sed '
    s/f/regular files/;t
    s/d/directories/;t
    s/l/symbolic links/;t
    s/s/Unix domain sockets/;t
    s/b/block devices/;t
    s/c/character devices/;t
    s/p/FIFOs/;t
    s/d/Doors/;t
    s/n/network special files/;t
    s/.$/others (&)/'

আমার উপর /usr/bin, যে দেয়:

   3711 regular files
    710 symbolic links

0

আপনি যদি বলেন না যে আপনি সমস্ত ফাইলটি / ইউএসআর / বিনের অধীনে বা কেবল প্রথম স্তরের অধীনে চান। এছাড়াও, আপনি যে শব্দগুলি গণনা করছেন তা কীভাবে পাবেন? সন্ধানের সাধারন উপায় হ'ল ডাব্লিউসি তে সন্ধান করা। এটি পছন্দ করুন: সন্ধান / usr / বিন | ডাব্লুসি-এল অনুসন্ধান সেখানে সমস্ত কিছু, ডিরেক্টরি এবং ফাইল তালিকাভুক্ত করবে। ডাব্লুসি-এল অনুসন্ধান ফলাফলের সমস্ত লাইন গণনা করবে। এটি কি ক্লাস অ্যাসাইনমেন্ট? এটি ঠিক আছে তবে আমি ভাবছিলাম যে আপনার কেন এই তথ্যের প্রয়োজন ছিল যাতে আমি আরও সতর্কতার সাথে প্রতিক্রিয়াটি তৈরি করতে পারি। আপনার আরও প্রয়োজন হলে আমাকে জানান। পঁজর


0

বাহিরে, বাহ্যিক সরঞ্জাম ছাড়াই।

cd dir/ || exit; shopt -s nullglob; shopt -s dotglob; count=(*); echo "${#count}"

ব্যাশে, বাহ্যিক সরঞ্জাম এবং পুনরাবৃত্তি ছাড়াই।

shopt -s globstar; shopt -s dotglob 
for dir in **/*/; do 
  unset d f
  for files in "$dir"*; do 
    [[ -f $files ]] && ((++f))
    [[ -d $files ]] && ((++d))
  done; 
  printf '%s\n' "$dir -  files: ${f:-0} - directories: ${d:-0}"
done

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