আমি কীভাবে `wc-l` এর সাথে একক মোট লাইন পেতে পারি?


12

আমার ইতিহাসে নির্দিষ্ট ফাইলগুলির লাইন গণনা দিতে আমি একটি গিট ওরফে যুক্ত করেছি:

[alias]
lines = !lc() { git ls-files -z ${1} | xargs -0 wc -l; }; lc

যাইহোক, wc -lএকাধিক মোটের প্রতিবেদন করা হচ্ছে, যেমন আমার কাছে যদি 100 ডলারের বেশি লাইন থাকে তবে এটি তাদের জন্য মোট রিপোর্ট করে, তারপরে এগিয়ে যায়। এখানে একটি উদাহরণ:

<100 কে লাইন (পছন্দসই আউটপুট)

$ git lines \*.xslt
  46 packages/NUnit-2.5.10.11092/doc/files/Summary.xslt
 232 packages/NUnit-2.5.10.11092/samples/csharp/_UpgradeReport_Files/UpgradeReport.xslt
 278 total

> 100 কে লাইন (এতে পাইপ দিতে হয়েছিল grep "total")

$ git lines \*.cs | grep "total"
 123569 total
 107700 total
 134796 total
 111411 total
  44600 total

wc -lসাবটোটেলের সিরিজ নয়, আমি কীভাবে সত্যিকারের মোট সংগ্রহ করব ?


স্ট্যাকওভারফ্লো / প্রশ্নগুলি / ২২৫০১০০/২ অনুসারে সমস্যাটি রয়েছে xargs, না wc। আমি কীভাবে এটি ঠিক করব সে বিষয়ে এখনও আগ্রহী এবং আমি উত্তরের কোনও ভাল সমাধান দেখতে পাচ্ছি না।
এহ্রাইক

3
আপনার সংস্করণ বিকল্প wcসমর্থন করে --files0-from? তারপরে আপনি এটি করতে পারেন{ git ls-files -z ${1} | wc -l --files0-from=- ; }
প্লটনিক 4

@ মার্কপ্লটনিক আমার কাছে মনে হয় যে এটির উত্তর পাওয়ার যোগ্য।
টেরডন

নাঃ। wc: unrecognized option '--files0-from=-'
এহ্রাইক

উত্তর:


12

এটি চেষ্টা করুন এবং সুস্পষ্ট হওয়ার জন্য ক্ষমা প্রার্থনা করুন:

cat *.cs | wc -l

বা, গিট সহ:

git ls-files -z ${1} | xargs -0 cat | wc -l

আপনি যদি wcস্বতন্ত্র গণনা এবং যোগফল উভয়ই আউটপুটটিকে আউটপুট মত দেখতে চান তবে আপনি awkপৃথক লাইন যুক্ত করতে ব্যবহার করতে পারেন:

git ls-files -z ${1} | xargs -0 wc -l |
awk '/^[[:space:]]*[[:digit:]]+[[:space:]]+total$/{next}
     {total+=$1;print}
     END {print total,"total"}'

এটি আপনার মতো wcগুরুত্বপূর্ণ ক্ষেত্রে যেমন সুন্দরভাবে সাজানো হবে না । এটি করার জন্য, আপনাকে সম্পূর্ণ ইনপুটটি পড়তে হবে এবং এটি সংরক্ষণ করতে হবে, মোট গণনা করা হবে এবং তারপরে মনে রাখা রেখাগুলির বিন্যাসিত আউটপুট মুদ্রণের জন্য ক্ষেত্রের প্রস্থটি ব্যবহারের আগে ক্ষেত্রের প্রস্থ গণনা করতে মোট ব্যবহার করতে হবে। বাড়ির সংস্কার প্রকল্পগুলির মতো, awkস্ক্রিপ্টগুলি কখনও সত্যই শেষ হয় না।

(উত্সাহী সম্পাদকদের কাছে দ্রষ্টব্য: প্রথম awkশর্তে নিয়মিত প্রকাশটি যদি এমন কোনও ফাইল থাকে যার নাম "মোট" এবং একটি স্পেস দিয়ে শুরু হয়; অন্যথায় শর্তটি আরও সহজতর হতে পারত $2 == "total"))


এটি কাজ করে তবে এটি কেবলমাত্র ( git ls-files -z ${1} | xargs -0 cat | wc -l) কে আউটপুট করে । তবে, আমার উপরের প্রথম উদাহরণে ডাব্লুসি-এল-র মতো প্রতি ফাইল-লাইন গণনাটি মিস করছি। এখানে উভয় বিশ্বের সেরা পেতে কোনও উপায়?
এহ্রাইক

অথবা, যদি এটি খুব কঠিন হয় তবে কীভাবে এমন একটি স্যুইচ সম্পর্কে যদি এটি ভেঙে যায়: কেবল মোট দিতে, যদি তা না হয় তবে মোট আউটপুট সহ ফাইলের জন্য স্বাভাবিক ডাব্লিউসি দিতে?
এহরিক

@ এহরিক: আপনি একবার grep -vকরে মোট লাইনগুলি ফেলে দেওয়ার জন্য একবার এটি করতে পেরেছিলেন এবং একবার মোট মোট প্রাপ্তির পরামর্শ দিয়েছিলেন। অথবা আপনি সম্পাদিত উত্তরে
বিশ্রী

+1: "বাড়ির সংস্কার প্রকল্পগুলির মতো, জোর স্ক্রিপ্টগুলি কখনই সত্যই সমাপ্ত হয় না।"
এহরিক

এটি যাদুর মতো কাজ করেছিল। আমার চূড়ান্ত ফলাফল:git ls-files -z ${1} | xargs -0 wc -l | awk '/^[[:space:]]*[[:digit:]]+[[:space:]]+total$/{next} {total+=$1;print} END {print "\n Total:",total,"lines"}'
এহ্রাইক

7

আপনি যদি লিনাক্স চালাচ্ছেন তবে আপনার wcসম্ভবত জিএনইউ করিউটিলস থেকে আসে এবং --files0-fromএকটি ফাইল (বা স্টিডিন) পড়ার একটি বিকল্প রয়েছে যা গণনা করার জন্য ফাইলের NUL- সমাপ্ত নামগুলির স্বতঃস্ফূর্ত দীর্ঘ তালিকা রয়েছে। গনুহ Coreutils wc-ডকুমেন্টেশন বলে "এটি দরকারী যখন ফাইলের নাম তালিকা এতক্ষণ এটি একটি কমান্ড লাইন দৈর্ঘ্য সীমাবদ্ধতা অতিক্রম করতে পারে না। এই ক্ষেত্রে, দৌড়ানো xargs মাধ্যমে wc-অবাঞ্ছিত কারণ এটি টুকরো তালিকা splits এবং wc-প্রিন্ট তোলে পুরো তালিকার চেয়ে প্রতিটি সাবলিস্টের জন্য মোট।

সুতরাং এটি চেষ্টা করুন:

lc() { git ls-files -z ${1} | wc -l --files0-from=- ; } 

সম্পাদনা: যেহেতু আপনার wcশেষ সহস্রাব্দ থেকে এসেছেন এবং সেই বিকল্পটি নেই, তাই ধরে নিই আরও একটি বহনযোগ্য সমাধান আপনার কাছে রয়েছে awkএবং "মোট" নামে কোনও ফাইল নেই। এটি যে wcকোনও totalলাইন বাদ দিয়ে পরিবর্তে সেগুলি সংমিশ্রণ করবে এবং শেষে গ্র্যান্ড টোটাল প্রিন্ট করবে of

একটি জিনিস যা আমি জানি না তা হ'ল gitউপনাম প্রয়োগের ক্ষেত্রে একক কোটগুলির অভ্যন্তর $1এবং $2অভ্যন্তরীণ সমস্যা রয়েছে , যা অপরিবর্তনীয়ভাবে পাস করা দরকার awk

lc() {
  git ls-files -z ${1} |
  xargs -0 wc -l |
  awk 'BEGIN { total=0; } { if (NF==2 && $2 == "total") total += $1; else print; } END { print total, "total"; }' ;
}

আমি লিনাক্স চালাচ্ছি না, এটি উইন্ডোজ এমএসজিগিত . github.io (এমএসএসজিট) এর জন্য গিটের গিট ব্যাশ প্রম্পটে রয়েছে ।
এহরিক

ঠিক আছে. সুতরাং xargsএবং wcতুমি চলমান Cygwin থেকে এসেছ? আপনি কি আউটপুট পেস্ট করতে পারেন wc --version?
প্লট্নিক

তারা একটি পূর্ণ সাইগউইন ইনস্টল থেকে নেই:$ wc --version wc (GNU textutils) 2.0 Written by Paul Rubin and David MacKenzie. Copyright (C) 1999 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
এহ্রিক

এটি উইন্ডোজ এক্সিকিউটেবলের জন্য একটি পূর্ণ,C:\Program Files (x86)\Git\bin\wc.exe
এহ্রাইক

@ এহরিক ম্যাসিসজিট লিনাক্স সরঞ্জামগুলির একটি বন্দর, তবে এটির পুরানো সংস্করণ রয়েছে, তাই এটি নাও থাকতে পারে --files0-from
গিলস 'অসন্তুষ্ট হওয়া বন্ধ করুন'

4

সমস্যাটি হ'ল xargsকমান্ডটি একাধিক রানে বিভক্ত করছে, তাই wcপ্রতিবারের জন্য মোট রিপোর্ট করা হচ্ছে। আপনার কাছে কয়েকটি বিকল্প রয়েছে, আপনি জিনিসগুলি সেভাবেই রাখতে পারেন এবং wcআউটপুটকে বিশ্লেষণ করতে পারেন :

git ls-files -z ${1} | xargs -0 wc -l | awk '/total/{k+=$1}END{print k,"total"}';

আপনি ফাইলগুলি বিড়াল করতে পারে:

git ls-files -z ${1} | xargs -0 cat | wc -l

অথবা আপনি xargsপুরোপুরি এড়িয়ে যেতে পারেন ( এখান থেকে অভিযোজিত ):

unset files i; while IFS= read -r -d $'\0' name; do 
 files[i++]="$name"; 
done < <(git ls-files -z ${1} ) && wc -l "${files[@]}"

যদি আপনার ফাইলগুলির তালিকা যদিও ARG_MAX এর চেয়ে দীর্ঘ হয় তবে তা ভঙ্গ হবে ।


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