UNIX الأوامر إلى قائمة المجلدات مع ملف التهم
سؤال
أريد الحصول على قائمة من المجلدات على المستوى الحالي (وليس بما في ذلك المجلدات الفرعية) و ببساطة طباعة اسم المجلد و عدد الملفات في المجلد (يفضل تصفية *.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]++ }'