سؤال

أريد الحصول على قائمة من المجلدات على المستوى الحالي (وليس بما في ذلك المجلدات الفرعية) و ببساطة طباعة اسم المجلد و عدد الملفات في المجلد (يفضل تصفية *.jpg إذا كان ذلك ممكنا).

هل هذا ممكن في مستوى باش قذيفة ؟ ls -l يطبع كل شيء ولكن عدد الملفات :)

هل كانت مفيدة؟

المحلول

وجئت مع هذا واحد:

find -maxdepth 1 -type d | while read dir; do 
    count=$(find "$dir" -maxdepth 1 -iname \*.jpg | wc -l)
    echo "$dir ; $count"
done

وإسقاط -maxdepth 1 الثانية إذا كان البحث في الدلائل عن ملفات JPG وينبغي أن تكون متكررة النظر في أدلة فرعية. لاحظ أن يراعي فقط اسم الملفات. هل يمكن إعادة تسمية ملف، يختبئ أنه صورة JPG. يمكنك استخدام الأمر file للقيام تخمين على المحتوى، بدلا من ذلك (الآن، كما يبحث بشكل متكرر):

find -mindepth 1 -maxdepth 1 -type d | while read dir; do 
    count=$(find "$dir" -type f | xargs file -b --mime-type | 
            grep 'image/jpeg' | wc -l)
    echo "$dir ; $count"
done

ولكن، وهذا هو أبطأ بكثير، نظرا لأنه يحتوي على قراءة جزء من الملفات وتفسير في نهاية المطاف ما كانت تحتوي على (إذا كان محظوظا، يجدها معرف سحرية في بداية الملف). و-mindepth 1 يمنعها من . الطباعة (الدليل الحالي)، ودليل آخر أن يبحث ذلك.

نصائح أخرى

لقد وجدت هذا السؤال بعد أن كنت قد اكتشفت بلدي النصي مماثل.يبدو لتناسب ظروف مرنة جدا حتى فكرت في إضافة على أنها إجابة.

المزايا:

  • يمكن تصنيفها إلى أي عمق (0 ., ، 1: المستوى الأول الدلائل ، إلخ.)
  • بصمات جميلة الإخراج
  • لا حلقة واحدة فقط find الأمر, حتى انها أسرع قليلا في الدلائل الكبيرة
  • لا يزال يمكن ضبطها لإضافة فلاتر مخصصة (maxdepth لجعله غير متكررة ، اسم الملف نمط)

الخام كود:

  find -P . -type f | rev | cut -d/ -f2- | rev | \
      cut -d/ -f1-2 | cut -d/ -f2- | sort | uniq -c

ملفوفة في وظيفة وأوضح:

fc() {
  # Usage: fc [depth >= 0, default 1]
  # 1. List all files, not following symlinks.
  #      (Add filters like -maxdepth 1 or -iname='*.jpg' here.)
  # 2. Cut off filenames in bulk. Reverse and chop to the
  #      first / (remove filename). Reverse back.
  # 3. Cut everything after the specified depth, so that each line
  #      contains only the relevant directory path
  # 4. Cut off the preceeding '.' unless that's all there is.
  # 5. Sort and group to unique lines with count.

  find -P . -type f \
      | rev | cut -d/ -f2- | rev \
      | cut -d/ -f1-$((${1:-1}+1)) \
      | cut -d/ -f2- \
      | sort | uniq -c
}

تنتج انتاج مثل هذا:

$ fc 0
1668 .

$ fc # depth of 1 is default
   6 .
   3 .ssh
  11 Desktop
  44 Downloads
1054 Music
 550 Pictures

طبعا مع الرقم الأول يمكن إيصاله إلى sort:

$ fc | sort
   3 .ssh
   6 .
  11 Desktop
  44 Downloads
 550 Pictures
1054 Music

والألغام أسرع إلى اكتب من سطر الأوامر. :)

والقيام الاقتراحات الأخرى تقدم أي ميزة حقيقية على ما يلي:؟

find -name '*.jpg' | wc -l               # recursive


find -maxdepth 1 -name '*.jpg' | wc -l   # current directory only
#!/bin/bash
for dir in `find . -type d | grep -v "\.$"`; do
echo $dir
ls $dir/*.jpg | wc -l
done;

ويمكنك أن تفعل ذلك دون أوامر الخارجية:

for d in */; do 
  set -- "$d"*.jpg
  printf "%s: %d\n" "${d%/}" "$#"
done

وأو يمكنك استخدام <م> AWK (<م> nawk أو <م> / البيرة / xpg4 / بن / AWK على <م> سولاريس ) :

printf "%s\n" */*jpg |
  awk -F\/ 'END { 
    for (d in _) 
      print d ":",_[d] 
      }
  { _[$1]++ }'
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top