استخدم Find و WC و SED لحساب الخطوط
سؤال
كنت أحاول استخدام SED لحساب جميع الخطوط بناءً على امتداد معين.
find -name '*.m' -exec wc -l {} \; | sed ...
كنت أحاول القيام بما يلي ، كيف يمكنني تضمين SED في هذا الخط بالذات للحصول على المجاميع.
المحلول
يمكنك أيضًا الحصول على التنسيق الجميل من WC مع:
wc `find -name '*.m'`
نصائح أخرى
لن تعمل معظم الإجابات هنا بشكل جيد لعدد كبير من الملفات. سوف يكسر البعض إذا كانت قائمة أسماء الملفات طويلة جدًا لمكالمة سطر أوامر واحد ، والبعض الآخر غير فعال بسبب -exec
يبدأ عملية جديدة لكل ملف. أعتقد أن الحل القوي والفعال سيكون:
find . -type f -name "*.m" -print0 | xargs -0 cat | wc -l
استخدام cat
وبهذه الطريقة على ما يرام ، حيث يتم إنتاجه مباشرة wc
لذلك يتم الاحتفاظ فقط بكمية صغيرة من محتوى الملفات في الذاكرة في وقت واحد. إذا كان هناك الكثير من الملفات لاستدعاء واحد cat
, cat
سيتم استدعاؤه عدة مرات ، ولكن كل الإخراج سيظل محجوزًا في واحدة wc
معالجة.
تستطيع cat
جميع الملفات من خلال واحد wc
مثيل للحصول على إجمالي عدد الخطوط:
find . -name '*.m' -exec cat {} \; | wc -l
على منصات GNU الحديثة مع معلمات Take -CRINT0 و -FILES0 -FROM التي يمكن دمجها في أمر يحسب الخطوط في الملفات مع المجموع في النهاية. مثال:
find . -name '*.c' -type f -print0 | wc -l --files0-from=-
يمكنك استخدام SED أيضًا لحساب الخطوط بدلاً من WC:
find . -name '*.m' -exec sed -n '$=' {} \;
أين '$='
هو "متغير خاص" يحافظ على عدد الخطوط
تعديل
يمكنك أيضًا تجربة شيء مثل sloccount
HM ، حل مع قطة قد تكون مشكلة إذا كان لديك العديد من الملفات ، وخاصة البيانات الكبيرة.
الحل الثاني لا يعطي المجموع ، فقط الخطوط لكل ملف ، كما اختبرت.
سأفضل شيئًا كهذا:
find . -name '*.m' | xargs wc -l | tail -1
سيؤدي ذلك إلى القيام بالمهمة بسرعة ، بغض النظر عن عدد الملفات التي لديك.
SED ليست الأداة المناسبة للعد. استخدم awk بدلاً من ذلك:
find . -name '*.m' -exec awk '{print NR}' {} +
باستخدام + بدلا من ؛ تجد القوات استدعاء AWK كل ملفات n الموجودة (مثل مع XARGS).
للحصول على الدلائل الكبيرة ، يجب أن نستخدم:
find . -type f -name '*.m' -exec sed -n '$=' '{}' + 2>/dev/null | awk '{ total+=$1 }END{print total}'
# alternative using awk twice
find . -type f -name '*.m' -exec awk 'END {print NR}' '{}' + 2>/dev/null | awk '{ total+=$1 }END{print total}'