ファイルの末尾の空白行の数を数える

ファイルの末尾の空白行の数を数える

ファイルの末尾に空白行があるファイルがあります。grepスクリプト内でファイル名を変数として渡して、ファイル末尾の空白行の数をカウントすることはできますか?

答え1

空白行がのみ最後に

grep  -c '^$' myFile

または:

grep -cx '' myFile

答え2

ただの楽しみのために、ちょっと不気味なものをsed:

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

説明:

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

答え3

その他の 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 が返されます。

POSIX 的には:

awk 'NF{n=NR};END{print NR-n}' < file

しかし、それはファイル全体を読み取ることを意味します ( tail -r/ はtacシーク可能なファイルの最後から逆方向にファイルを読み取ります)。これにより、1の出力が得られますprintf 'x\n '

答え4

あなたが実際に求めているのは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 ".*"行数をカウントできます。

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

関連情報