ফাইলটির শেষে ফাঁকা লাইন সহ আমার একটি ফাইল রয়েছে। grep
স্ক্রিপ্টে ভেরিয়েবল হিসাবে ফাইলের নামটি পাস করার পরে আমি ফাইলটির শেষে ফাঁকা রেখার সংখ্যা গণনা করতে পারি ?
grep
আমার বইতে বিশুদ্ধতার জন্য @ মিশেল জন জয়ের জন্য বলেছে ।
ফাইলটির শেষে ফাঁকা লাইন সহ আমার একটি ফাইল রয়েছে। grep
স্ক্রিপ্টে ভেরিয়েবল হিসাবে ফাইলের নামটি পাস করার পরে আমি ফাইলটির শেষে ফাঁকা রেখার সংখ্যা গণনা করতে পারি ?
grep
আমার বইতে বিশুদ্ধতার জন্য @ মিশেল জন জয়ের জন্য বলেছে ।
উত্তর:
যদি ফাঁকা লাইনগুলি কেবল শেষে থাকে
grep -c '^$' myFile
বা:
grep -cx '' myFile
grep -cv . myFile
এটি লেখার আরেকটি উপায় (কোড গল্ফারদের জন্য)। তবে আমি grep
ফাইলটির কোথাও খালি লাইন থাকলে একটি সমাধান পেয়েছি ।
grep -cv .
এমন লাইনগুলিও গণনা করবে যাতে কেবলমাত্র বাইট থাকে যা বৈধ অক্ষর তৈরি করে না।
কেবল মজাদার জন্য, কিছু ভুতুড়ে sed
:
#!/bin/sh
sed '/./!H;//h;$!d;//d;x;s/\n//' "$1" | wc -l
ব্যাখ্যা:
/./
যে কোনও অক্ষরের সাথে লাইনগুলিকে সম্বোধন করে, তাই /./!
শূন্য নয় লাইনগুলি সম্বোধন করে; তাদের জন্য, H
কমান্ড তাদের হোল্ড স্পেসে যুক্ত করবে। সুতরাং, যদি প্রতিটি খালি লাইনের জন্য আমরা হোল্ড স্পেসে একটি লাইন যুক্ত করে থাকি তবে সবসময় খালি লাইনের সংখ্যার চেয়ে আরও একটি লাইন থাকে। আমরা পরে এটি যত্ন করব।//h
খালি প্যাটার্নটি সর্বশেষ নিয়মিত প্রকাশের সাথে মেলে যা কোনও চরিত্র ছিল, সুতরাং যে কোনও ফাঁকা লাইন সম্বোধন করে সংগ্রহ করা লাইনগুলিকে "পুনরায় সেট করতে" কমান্ড দ্বারা হোল্ড স্পেসে স্থানান্তরিত করা h
হয়। যখন পরবর্তী ফাঁকা লাইন যুক্ত হবে, প্রত্যাশা অনুযায়ী আবার দু'জন আসবে।$!d
শেষ লাইনটি ছাড়াও স্ক্রিপ্টটি আউটপুট ছাড়াই থামায়, সুতরাং আরও কমান্ড কেবল শেষ লাইনের পরে কার্যকর করা হবে। সুতরাং আমরা হোল্ড স্পেসে যা কিছু খালি লাইন সংগ্রহ করেছি তা ফাইলের শেষে। ভাল.//d
: d
কমান্ডটি কেবলমাত্র খালি খালি লাইনের জন্যই কার্যকর করা হয়। সুতরাং যদি শেষ লাইনটি খালি না থাকে তবে sed
কোনও আউটপুট ছাড়াই প্রস্থান করবে। শূন্য লাইন। ভাল.x
এক্সচেঞ্জগুলি স্থান এবং প্যাটার্ন স্পেস ধারণ করে, তাই সংগ্রহ করা লাইনগুলি এখন প্রক্রিয়া করার জন্য প্যাটার্ন স্পেসে রয়েছে।s/\n//
।wc -l
।আরও কিছু জিএনইউ tac
/ tail -r
বিকল্পসমূহ:
tac file | awk 'NF{exit};END{print NR?NR-1:0}'
বা:
tac file | sed -n '/[^[:blank:]]/q;p' | wc -l
মনে রাখবেন যে এর ফলাফল:
printf 'x\n '
এটি হ'ল, সর্বশেষ পূর্ণ লাইনের পরে যেখানে অতিরিক্ত স্থান রয়েছে (যা কিছু লোক অতিরিক্ত ফাঁকা রেখা হিসাবে বিবেচনা করতে পারে তবে পাঠ্যের POSIX সংজ্ঞা অনুসারে বৈধ পাঠ্য নয়), সেগুলি 0 দেবে।
POSIXly:
awk 'NF{n=NR};END{print NR-n}' < file
তবে এর অর্থ ফাইলটি পুরোপুরি পড়া ( tail -r
/ tac
সন্ধানযোগ্য ফাইলগুলির মধ্যে ফাইলটি শেষ থেকে পিছিয়ে পড়া হবে)। যে 1
আউটপুট দেয় printf 'x\n '
।
আপনি যেমন কোনও grep
সমাধানের জন্য জিজ্ঞাসা করছেন আমি কেবল এটি জিএনইউতে নির্ভর করে এটি যুক্ত করি grep
(ঠিক আছে, শেল সিনট্যাক্স এবং echo
...) ব্যবহার করে :
#!/bin/sh
echo $(( $(grep -c "" "$1") - $(grep -B$(grep -cv . "$1") . "$1" |grep -c "") ))
আমি এখানে কি করছেন? $(grep -c ".*" "$1")
ফাইলের সমস্ত লাইন গণনা করা হয়, তারপরে আমরা ফাঁকা লাইনগুলি অনুসরণ না করে ফাইলটি বিয়োগ করতে পারি।
এবং কিভাবে এটি পেতে? $(grep -B42 . "$1"
সমস্ত খালি-ফাঁকা রেখা এবং তাদের আগে 42 লাইন গ্রেপ করে দেবে, সুতরাং এটি সর্বশেষ নন-খালি লাইন পর্যন্ত মুদ্রণ করবে, যতক্ষণ না খালি খালি লাইনের আগে পরপর 42 টির বেশি খালি লাইন না থাকে। এই সীমাটি এড়াতে, আমি বিকল্পটির $(grep -cv . "$1")
প্যারামিটার হিসাবে নিই -B
, যা খালি লাইনের মোট সংখ্যা, তাই সর্বদা যথেষ্ট বড়। এইভাবে আমি খালি লাইনগুলি অনুসরণ করে চলেছি এবং লাইনগুলি |grep -c ".*"
গণনা করতে ব্যবহার করতে পারি ।
উজ্জ্বল, তাই না? (-;
tac | grep
প্রথমে শূন্য নয় -m -A 42
, তারপরে বিয়োগ করবে। আমি নিশ্চিত কোনটি আরও কার্যকর, তবে আপনি wc -l | cut -d' ' -f1
ফাঁকা লাইনগুলি চেপে ধরার পরিবর্তেও পারতেন ?
tac
, wc
এবং cut
, কিন্তু এখানে আমি নিজেকে সীমাবদ্ধ করার চেষ্টা grep
। আপনি এটিকে বিকৃতি বলতে পারেন, আমি এটিকে স্পোর্টস বলি। (-;
আর একটি awk
সমাধান। এই প্রকরণটি k
প্রতিবার একটি খালি ফাঁকা রেখা না থাকলে কাউন্টারটিকে পুনরায় সেট করে । তারপরে, প্রতিটি লাইন কাউন্টারকে বাড়িয়ে দেয়। (সুতরাং, প্রথম প্রথম খালি দৈর্ঘ্যের লাইন পরে k==0
।) শেষে আমরা গণনা করা রেখার সংখ্যা আউটপুট করি।
ডেটা ফাইল প্রস্তুত করুন
cat <<'X' >input.txt
aaa
bbb
ccc
X
নমুনায় পিছনের ফাঁকা রেখা গণনা করুন
awk 'NF {k=-1}; {k++}; END {print k+0}' input.txt
3
এই সংজ্ঞায়, একটি ফাঁকা রেখায় ফাঁকা স্থান বা অন্যান্য ফাঁকা অক্ষর থাকতে পারে; এটি এখনও ফাঁকা আপনি যদি খালি লাইনের পরিবর্তে খালি লাইন গণনা করতে চান তবে এর জন্য পরিবর্তন NF
করুন $0 != ""
।
$0 > ""
? যে ব্যবহারসমূহ strcoll()
যা কম দক্ষ হবে চেয়ে $0 != ""
যা ব্যবহার memcmp()
অনেক বাস্তবায়নের মধ্যে (POSIX ব্যবহার করার জন্য এটি প্রয়োজন ব্যবহৃত strcoll()
যদিও)।
$0 > ""
চেয়ে আলাদা হতে পারিনি $0 != ""
। আমি awk
যাইহোক "ধীর" অপারেটর হিসাবে আচরণ করব (যেমন যদি আমি জানতে পারি যে ইনপুট হিসাবে আমার একটি বড় ডেটাসেট পেয়েছে এবং প্রক্রিয়াজাতকরণ সময় সমালোচিত হয়, তবে আমি পরিমাণটি হ্রাস করতে কী করতে পারি awk
তা প্রক্রিয়া করতে হবে - আমি grep | awk
যেমন পরিস্থিতিতে নির্মাণ ব্যবহার করেছেন )। যাইহোক, আমি কী ধরে নিয়েছি সে সম্পর্কে একটি তাত্ক্ষণিক দৃষ্টি আকর্ষণ করা হ'ল আমি পসিক্স সংজ্ঞাটি হয় strcoll()
বা আমি এর কোনও উল্লেখ দেখতে পাই না memcmp()
। আমি কী মিস করছি?
strcoll()
== স্ট্রিংগুলি লোকেল-নির্দিষ্ট কোলেশন ক্রম ব্যবহার করে তুলনা করা হবে । আগের সংস্করণের সাথে তুলনা করুন । আমিই এটিকে তুলে আনি। আরও দেখুন austingroupbugs.net/view.php?id=963
a <= b && a >= b
অগত্যা একইরকম নয় a == b
। সেকি!
awk
বা bash
(তার জন্য [[ a < b ]]
জন্য উদাহরণস্বরূপ গনুহ সিস্টেমে en_US.UTF -8 লোকেলে অপারেটার) ①
বনাম ②
উদাহরণস্বরূপ (জন্য bash
, কেউ <
, >
, =
তাদের জন্য সত্য ফিরে)। তাত্ক্ষণিকভাবে এটি বাশ / অ্যাডাব্লিকের চেয়ে এই লোকেলগুলির সংজ্ঞায় একটি বাগ
ফাইলের শেষে একটানা ফাঁকা রেখার সংখ্যা গণনা করতে
সলিড awk
+ tac
সমাধান:
নমুনা input.txt
:
$ cat input.txt
aaa
bbb
ccc
$ # command line
ক্রিয়া:
awk '!NF{ if (NR==++c) { cnt++ } else exit }END{ print int(cnt) }' <(tac input.txt)
!NF
- বর্তমান লাইনটি খালি রয়েছে তা নিশ্চিত করে (কোনও ক্ষেত্র নেই)NR==++c
- ফাঁকা লাইনের একটানা ক্রম নিশ্চিত করা। ( NR
- রেকর্ড নম্বর, ++c
- সমানভাবে বর্ধিত সহায়ক কাউন্টার)cnt++
- ফাঁকা লাইনের কাউন্টারআউটপুট:
3
আইআইইউসি, নিম্নলিখিত স্ক্রিপ্ট count-blank-at-the-end.sh
কাজ করবে:
#!/usr/bin/env sh
count=$(tail -n +"$(grep . "$1" -n | tail -n 1 | cut -d: -f1)" "$1" | wc -l)
num_of_blank_lines=$((count - 1))
printf "%s\n" "$num_of_blank_lines"
ব্যবহারের উদাহরণ:
$ ./count-blank-at-the-end.sh FILE
4
আমি এটা পরীক্ষিত GNU bash
, Android mksh
এবং ksh
।
বিকল্প Python
সমাধান:
নমুনা ইনপুট.টেক্সট:
$ cat input.txt
aaa
bbb
ccc
$ # command line
ক্রিয়া:
python -c 'import sys, itertools; f=open(sys.argv[1]);
lines=list(itertools.takewhile(str.isspace, f.readlines()[::-1]));
print(len(lines)); f.close()' input.txt
আউটপুট:
3
https://docs.python.org/3/library/itertools.html?highlight=itertools#itertools.takewhile