ファイルの最後に空白行があるファイルがあります。 grep
を使用して、ファイル名がスクリプトで変数として渡されているファイルの最後の空白行の数をカウントできますか?
空白行が最後にonlyの場合
grep -c '^$' myFile
または:
grep -cx '' myFile
ちょうど楽しみのために、いくつかの不気味な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//
を使用して改行を1行削除することで、1行を減らしています。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
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 ".*"
_を使用して行をカウントできます。
素晴らしいですよね? (-;
別の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
を変更します。
ファイルの終わりにある連続する空白行の数を数える
固体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
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