
ファイルの末尾に空白行があるファイルがあります。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 ".*"
行数をカウントできます。
素晴らしいですね。(-;