كيفية عد الأسطر من التعليمات البرمجية بما في ذلك الدلائل الفرعية [مكررة]

StackOverflow https://stackoverflow.com/questions/316590

  •  11-07-2019
  •  | 
  •  

سؤال

لنفترض أنني أريد أن عد الأسطر من التعليمات البرمجية في المشروع.إذا كان كل من الملفات في نفس الدليل لا يمكن تنفيذ:

cat * | wc -l

ومع ذلك ، إذا كان هناك الدلائل الفرعية, هذا لا يعمل.هذا القط يجب أن يكون وضع العودية.وأظن أن هذا قد يكون عمل xargs ، ولكن أنا أتساءل عما إذا كان هناك أكثر أناقة الحل ؟

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

المحلول

أولا لا تحتاج إلى استخدام cat لحساب الخطوط.هذا نمط مضاد يسمى الاستخدام عديم الفائدة للقطط (UUoC).لحساب الأسطر في الملفات الموجودة في الدليل الحالي، استخدم wc:

wc -l * 

ثم find يكرر الأمر الدلائل الفرعية:

find . -name "*.c" -exec wc -l {} \;
  • . هو اسم الدليل العلوي لبدء البحث منه

  • -name "*.c" هو نمط الملف الذي تهتم به

  • -exec يعطي الأمر ليتم تنفيذه

  • {} هي نتيجة أمر البحث المراد تمريره إلى الأمر (هنا wc-l)

  • \; يشير إلى نهاية الأمر

ينتج هذا الأمر قائمة بجميع الملفات التي تم العثور عليها مع عدد الأسطر الخاصة بها، إذا كنت تريد الحصول على مجموعها الجميع الملفات التي تم العثور عليها، يمكنك استخدام البحث لسرد الملفات (مع ملحق -print الخيار) ومن استخدام xargs لتمرير هذه القائمة كوسيطة إلى wc-l.

find . -name "*.c" -print | xargs wc -l 

قم بالتحرير لمعالجة تعليق روبرت غامبل (شكرًا):إذا كان لديك مسافات أو أسطر جديدة (!) في أسماء الملفات، فيجب عليك استخدامها -print0 الخيار بدلا من -print و xargs -null بحيث يتم تبادل قائمة أسماء الملفات بسلاسل منتهية بقيمة خالية.

find . -name "*.c" -print0 | xargs -0 wc -l

تتمثل فلسفة يونكس في امتلاك الأدوات التي تفعل شيئًا واحدًا فقط، وتفعله بشكل جيد.

نصائح أخرى

إذا كنت تريد مدونة-الغولف الجواب:

grep '' -R . | wc -l 

المشكلة فقط باستخدام wc-l تلقاء نفسه هل هو قادر ينزل حسنا ، oneliners باستخدام

find . -exec wc -l {} \;

لن تعطيك مجموع خط العد لأنه يعمل wc مرة واحدة لكل ملف ( لول!) و

find . -exec wc -l {} + 

سوف تحصل على الخلط حالما تجد يضرب ~200k1,2 حرف حجة حد المعلمات بدلا المكالمات wc متعددة مرات, في كل مرة فقط مما يتيح لك الجزئي ملخص.

بالإضافة إلى ذلك أعلاه البقرى خدعة لن تضيف أكثر من 1 خط الانتاج عندما يواجه ملف ثنائي ، التي يمكن أن تكون circumstantially مفيدة.

تكلفة 1 إضافية القيادة الشخصية ، يمكنك تجاهل الملفات الثنائية تماما:

 grep '' -IR . | wc -l

إذا كنت ترغب في تشغيل خط التهم على الملفات الثنائية أيضا

 grep '' -aR . | wc -l 
حاشية على الحدود:

المستندات هي غامضة بعض الشيء عما إذا كان لها سلسلة الحد الأقصى لحجم أو عدد من الرموز الحد.

cd /usr/include;
find -type f -exec perl -e 'printf qq[%s => %s\n], scalar @ARGV, length join q[ ], @ARGV' {} + 
# 4066 => 130974
# 3399 => 130955
# 3155 => 130978
# 2762 => 130991
# 3923 => 130959
# 3642 => 130989
# 4145 => 130993
# 4382 => 130989
# 4406 => 130973
# 4190 => 131000
# 4603 => 130988
# 3060 => 95435

وهذا يعني الذهاب إلى قطعة بسهولة جدا جدا.

أعتقد أنك ربما تكون عالقًا مع xargs

find -name '*php' | xargs cat | wc -l

com.chromakodeطريقة تعطي نفس النتيجة ولكنها أبطأ بكثير.إذا كنت تستخدم xargs الخاص بك قطةجي و مرحاضيمكن أن تبدأ في أقرب وقت يجد يبدأ في العثور على.

شرح جيد في لينكس:xargs مقابل.تنفيذي {}

حاول استخدام find الأمر، الذي يكرر الدلائل بشكل افتراضي:

find . -type f -execdir cat {} \; | wc -l

الطريقة الصحيحة هي:

find . -name "*.c" -print0 | xargs -0 cat | wc -l

يجب عليك استخدام -print0 نظرًا لوجود حرفين غير صالحين فقط في أسماء ملفات Unix:البايت الفارغ و"/" (شرطة مائلة).على سبيل المثال، يعد "xxx passwd" اسمًا صالحًا.في الواقع، من المرجح أن تواجه أسماء بها مسافات.الأوامر المذكورة أعلاه تحسب كل كلمة كملف منفصل.

قد ترغب أيضًا في استخدام "-type f" بدلاً من -name لتقييد البحث بالملفات.

يعد استخدام cat أو grep في الحلول المذكورة أعلاه إهدارًا إذا كان بإمكانك استخدام أدوات GNU الحديثة نسبيًا، بما في ذلك Bash:

wc -l --files0-from=<(find . -name \*.c -print0)

يعالج هذا أسماء الملفات بمسافات، والتكرار العشوائي وأي عدد من الملفات المطابقة، حتى لو تجاوزت الحد الأقصى لطول سطر الأوامر.

أحب أن استخدم يجد و رأس معًا للحصول على "قطة متكررة" على كافة الملفات الموجودة في دليل المشروع، على سبيل المثال:

find . -name "*rb" -print0 | xargs -0 head -10000

الميزة هي أن الرأس سيضيف اسم الملف والمسار:

==> ./recipes/default.rb <==
DOWNLOAD_DIR = '/tmp/downloads'
MYSQL_DOWNLOAD_URL = 'http://cdn.mysql.com/Downloads/MySQL-5.6/mysql-5.6.10-debian6.0-x86_64.deb'
MYSQL_DOWNLOAD_FILE = "#{DOWNLOAD_DIR}/mysql-5.6.10-debian6.0-x86_64.deb"

package "mysql-server-5.5"
...

==> ./templates/default/my.cnf.erb <==
#
# The MySQL database server configuration file.
#
...

==> ./templates/default/mysql56.sh.erb <==
PATH=/opt/mysql/server-5.6/bin:$PATH 

للحصول على المثال الكامل هنا، يرجى الاطلاع على مشاركة مدونتي:

http://haildata.net/2013/04/using-cat-recursively-with-nicely-formatted-output- Included-headers/

لاحظ أنني استخدمت "head -10000"، ومن الواضح أنه إذا كان لدي ملفات تزيد عن 10000 سطر، فسيؤدي ذلك إلى اقتطاع الإخراج ...ومع ذلك يمكنني استخدام الرأس 100000 ولكن بالنسبة "للتصفح غير الرسمي للمشروع/الدليل" فإن هذا الأسلوب يعمل جيدًا بالنسبة لي.

إذا كنت تريد إنشاء إجمالي عدد الأسطر فقط وليس عدد الأسطر لكل ملف، مثل:

find . -type f -exec wc -l {} \; | awk '{total += $1} END{print total}'

يعمل بشكل جيد.وهذا يوفر عليك الحاجة إلى إجراء المزيد من تصفية النص في البرنامج النصي.

wc -cl `find . -name "*.php" -type f`

إليك برنامج Bash النصي الذي يقوم بإحصاء أسطر التعليمات البرمجية في المشروع.فهو يجتاز الشجرة المصدر بشكل متكرر، ويستبعد الأسطر الفارغة وتعليقات الأسطر المفردة التي تستخدم "//".

# $excluded is a regex for paths to exclude from line counting
excluded="spec\|node_modules\|README\|lib\|docs\|csv\|XLS\|json\|png"

countLines(){
  # $total is the total lines of code counted
  total=0
  # -mindepth exclues the current directory (".")
  for file in `find . -mindepth 1 -name "*.*" |grep -v "$excluded"`; do
    # First sed: only count lines of code that are not commented with //
    # Second sed: don't count blank lines
    # $numLines is the lines of code
    numLines=`cat $file | sed '/\/\//d' | sed '/^\s*$/d' | wc -l`
    total=$(($total + $numLines))
    echo "  " $numLines $file
  done
  echo "  " $total in total
}

echo Source code files:
countLines
echo Unit tests:
cd spec
countLines

إليك ما يبدو عليه الإخراج مشروعي:

Source code files:
   2 ./buildDocs.sh
   24 ./countLines.sh
   15 ./css/dashboard.css
   53 ./data/un_population/provenance/preprocess.js
   19 ./index.html
   5 ./server/server.js
   2 ./server/startServer.sh
   24 ./SpecRunner.html
   34 ./src/computeLayout.js
   60 ./src/configDiff.js
   18 ./src/dashboardMirror.js
   37 ./src/dashboardScaffold.js
   14 ./src/data.js
   68 ./src/dummyVis.js
   27 ./src/layout.js
   28 ./src/links.js
   5 ./src/main.js
   52 ./src/processActions.js
   86 ./src/timeline.js
   73 ./src/udc.js
   18 ./src/wire.js
   664 in total
Unit tests:
   230 ./ComputeLayoutSpec.js
   134 ./ConfigDiffSpec.js
   134 ./ProcessActionsSpec.js
   84 ./UDCSpec.js
   149 ./WireSpec.js
   731 in total

يتمتع!--كوران

find . -name "*.h" -print | xargs wc -l
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top