ファイルの最後に空白行があるファイルがあります。grepスクリプトで変数として渡されるファイル名を使用して、ファイルの最後にある空白行の数を数えるのに使用できますか?
grep、私の本の中で純粋さのために@MichaelJohnの勝利を求めました。
                ファイルの最後に空白行があるファイルがあります。grepスクリプトで変数として渡されるファイル名を使用して、ファイルの最後にある空白行の数を数えるのに使用できますか?
grep、私の本の中で純粋さのために@MichaelJohnの勝利を求めました。
                回答:
空白行が最後にのみある場合
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コマンドはそれらをホールドスペースに追加します。したがって、空の各行についてホールドスペースに1行追加した場合、空の行の数よりも常に1行多くなります。後で気にします。//h空のパターンは最後の正規表現と一致します。これは任意の文字でした。そのため、空ではない行はコマンドによってアドレス指定されてホールドスペースに移動しh、収集された行を1に「リセット」します。次の空の行が追加されると、予想通り、再び2つあります。$!d最後の行以外は出力せずにスクリプトを停止するため、以降のコマンドは最後の行の後にのみ実行されます。したがって、ホールドスペースに収集した空の行はすべてファイルの最後にあります。良い。//d:d空でない行に対してのみコマンドが再度実行されます。したがって、最後の行が空でなければ、sed何も出力されずに終了します。ゼロ線。良い。x 交換はスペースとパターンスペースを保持するため、収集されたラインはパターンスペースにあり、処理されます。s/\n//。wc -l。さらにいくつかの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 '。
あなたが実際に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 ".*"カウントに使用できます。
素晴らしいですね。(-;
tac | grep、最初の非空白文字に-m -A 42、次にマイナス1にすることです。どちらがより効率的wc -l | cut -d' ' -f1かはわかりませんが、空白行をgrepする代わりにできますか?
                    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処理しなければならないが- I grep | awkこのような状況で構造体を使用しています。)ただし、POSIXの定義と思われるものをざっと見てみると、strcoll()またはのいずれも参照できませんmemcmp()。何が欠けていますか?
                    strcoll()== 文字列は、ロケール固有の照合シーケンスを使用して比較されます。前の版と比較してください。私はそれを育てた人でした。参照してくださいaustingroupbugs.net/view.php?id=963
                    a <= b && a >= bは、必ずしもと同じではない実装a == bです。痛い!
                    awkまたはbash(そのため[[ a < b ]]のインスタンスのためのGNUシステム上EN_US.UTF-8ロケールでオペレータ)①対②(のインスタンスのためbashのどれも、<、>、=それらのためにtrueを返します)。おそらくそれは、よりbashの/ awkではよりも、これらのロケールの定義にバグです
                    ファイルの最後にある連続する空白行の数を数える
固体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
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 bash、Android mkshそして中ksh。
代替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