web-dev-qa-db-ja.com

ファイルの終わりにある空白行の数を数える

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

11

空白行が最後にonlyの場合

grep  -c '^$' myFile

または:

grep -cx '' myFile
11
bu5hman

ちょうど楽しみのために、いくつかの不気味な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行が多すぎることを覚えているので、s/\n//を使用して改行を1行削除することで、1行を減らしています。
  • ほら!行数は最後の空行の数と一致します(最初の行は空ではありませんが、誰が気にかけることに注意してください)。したがって、wc -lでそれらを数えることができます。
11
Philippos

もう少し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 '

8

grep solutionを実際に求めているので、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 ".*"_を使用して行をカウントできます。

素晴らしいですよね? (-;

6
Philippos

別のawkソリューション。このバリエーションは、空でない行があるたびにカウンターkをリセットします。次に、すべての行がカウンターを増分します。 (つまり、最初の空白でない長さの行の後、k==0。)最後に、カウントした行数を出力します。

データファイルを準備する

cat <<'X' >input.txt
aaa

bbb
ccc



X

サンプルの末尾の空白行を数える

awk 'NF {k=-1}; {k++}; END {print k+0}' input.txt
3

この定義では、空白行にはスペースまたはその他の空白文字が含まれる場合があります。それはまだ空白です。空白行ではなく空行を数えたい場合は、$0 != ""NFを変更します。

5
roaima

ファイルの終わりにある連続する空白行の数を数える

固体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-現在の行がemptyであることを確認します(フィールドがない)
  • NR==++c-空白行の連続順序を保証します。 (NR-レコード番号、++c-均等にインクリメントされた補助カウンター)
  • cnt++-blank行のカウンター

出力:

3
2
RomanPerekhrest

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 mkshkshでテストしました。

1

代替Pythonソリューション:

Input.txtの例:

$ 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

0
RomanPerekhrest