ファイルの最後の空白行の数を数えます


11

ファイルの最後に空白行があるファイルがあります。grepスクリプトで変数として渡されるファイル名を使用して、ファイルの最後にある空白行の数を数えるのに使用できますか?


連続する空白行の数をカウントするには
RomanPerekhrest 2017年

2
@RomanPerekhrestそうだとしたら、そうでなければ「ファイルの最後」にはならないでしょうか?
スパーホーク2017年

'grep -cv -P' \ S 'filename'は、ファイル内の空白行の総数をカウントします。最後の数字は私の脳に負担をかけるだけです!
MichaelJohn 2017年

OPはgrep、私の本の中で純粋さのために@MichaelJohnの勝利を求めました。
bu5hman 2017年

2
@ bu5hmanしかし、彼が認めるように、質問には答えません。本当にあなたのものもそうではありません。
Sparhawk 2017年

回答:


11

空白行が最後にのみある場合

grep  -c '^$' myFile

または:

grep -cx '' myFile

秒単位で編集に
打ちのめさ

grep -cv . myFileそれを書く別の方法です(コードゴルファー向け)。しかしgrep、ファイル内のどこかに空の行がある場合の解決策を見つけました。
フィリポス

2
@Philipposは、grep -cv .有効な文字を形成しないバイトのみを含む行もカウントします。
ステファンシャゼラス

11

楽しみのために、いくつかの不気味なsed

#!/bin/sh
sed '/./!H;//h;$!d;//d;x;s/\n//' "$1" | wc -l

説明:

  • /./任意の文字で行をアドレス指定するため、/./!空でない行をアドレス指定します。それらの場合、Hコマンドはそれらをホールドスペースに追加します。したがって、空の各行についてホールドスペースに1行追加した場合、空の行の数よりも常に1行多くなります。後で気にします。
  • //h空のパターンは最後の正規表現と一致します。これは任意の文字でした。そのため、空ではない行はコマンドによってアドレス指定されてホールドスペースに移動h、収集された行を1に「リセット」します。次の空の行が追加されると、予想通り、再び2つあります。
  • $!d最後の行以外は出力せずにスクリプトを停止するため、以降のコマンドは最後の行の後にのみ実行されます。したがって、ホールドスペースに収集した空の行はすべてファイルの最後にあります。良い。
  • //dd空でない行に対してのみコマンドが再度実行されます。したがって、最後の行が空でなければ、sed何も出力されずに終了します。ゼロ線。良い。
  • x 交換はスペースとパターンスペースを保持するため、収集されたラインはパターンスペースにあり、処理されます。
  • しかし、1行が多すぎることを覚えているので、で改行を1つ削除することでそれを減らしますs/\n//
  • ほら!行数は最後の空行の数と一致するため(最初の行は空ではないが、誰が気にするか)、したがってで数えることができますwc -l

8

さらにいくつかのGNU 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 '


6

あなたが実際にgrep解決策を求めているので、私はこれをGNUにのみ依存するものを追加しますgrep(そうです、シェル構文も使用していますecho...):

#!/bin/sh
echo $(( $(grep -c "" "$1") - $(grep -B$(grep -cv . "$1") . "$1" |grep -c "") ))

私はここで何をしているんだ?$(grep -c ".*" "$1")ファイル内のすべての行を数え、最後の空行を除いてファイルを減算します。

そして、それらを取得する方法?$(grep -B42 . "$1"空でないすべての行とその前の42行をすべてgrepするため、空でない行の前に連続する空の行が42行を超えない限り、最後の空でない行まですべてが出力されます。この制限を回避するために、空行の総数であるオプション$(grep -cv . "$1")のパラメーターとして、-B常に十分な大きさをとっています。このようにして、末尾の空の行を取り除き、行の|grep -c ".*"カウントに使用できます。

素晴らしいですね。(-;


+1それは恐ろしいコードですが、質問どおりに技術的に答えており、あなたをマークダウンすることはできません
;

グレプマイスター。私たちはふさわしくない。
bu5hman 2017年

邪悪さのために+1。別の(おそらくより速い?)オプションはtac | grep、最初の非空白文字に-m -A 42、次にマイナス1にすることです。どちらがより効率的wc -l | cut -d' ' -f1かはわかりませんが、空白行をgrepする代わりにできますか?
スパーホーク2017年

はい、確かに、あなたが多くのことを行うことができtacwcそしてcut、しかし、ここで私はに自分自身を制限しようとしましたgrep。あなたはそれを倒錯と呼ぶことができます、私はそれをスポーツと呼びます。(-;
フィリポス

5

別の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()かかわらず)。
ステファンシャゼル

@StéphaneChazelas私はそれとは$0 > ""違うかもしれないとは考えていません$0 != ""。私は治療のために傾向があるawk私は、入力や処理などの大きなデータセットを持って知っていれば時間が重要である、私は量削減に何ができるかがわかりますよう(とにかく「遅い」演算子としてawk処理しなければならないが- I grep | awkこのような状況で構造体を使用しています。)ただし、POSIXの定義と思われるものをざっと見てみると、strcoll()またはのいずれも参照できませんmemcmp()。何が欠けていますか?
roaima 2017年

strcoll()== 文字列は、ロケール固有の照合シーケンスを使用して比較されます前の版と比較してください。私はそれを育てた人でした。参照してくださいaustingroupbugs.net/view.php?id=963
ステファンChazelas

@StéphaneChazelas a <= b && a >= bは、必ずしもと同じではない実装a == bです。痛い!
roaima

すなわち、GNUのケースのawkまたはbash(そのため[[ a < b ]]のインスタンスのためのGNUシステム上EN_US.UTF-8ロケールでオペレータ)(のインスタンスのためbashのどれも、<>=それらのためにtrueを返します)。おそらくそれは、よりbashの/ awkではよりも、これらのロケールの定義にバグです
ステファンChazelas

2

ファイルの最後にある連続する空白行の数を数える

固体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

1

IIUC、呼び出される次のスクリプト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 bashAndroid mkshそして中ksh


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.