计算文件末尾的空行数


11

我有一个文件末尾有空白行的文件。我可以使用grep文件名作为脚本中的变量来传递文件末尾的空行数吗?


计算连续空白行的数量
RomanPerekhrest

2
@RomanPerekhrest我会这么说,否则它们不会在“文件末尾”吗?
Sparhawk

'grep -cv -P'\ S'filename'将计算文件中空白行的总数。最后的数字只会让我感到头疼!
MichaelJohn

OP要求grep@MichaelJohn在我的书中获得纯正。
bu5hman

2
@ bu5hman但是(他承认)没有回答这个问题。您的也没有。
Sparhawk

Answers:


11

如果空白行在末尾

grep  -c '^$' myFile

要么:

grep -cx '' myFile

该死的被编辑
击败

grep -cv . myFile是另一种编写方法(适用于代码高尔夫球手)。但是我找到了一个解决方案,grep如果文件中的任何地方都有空行。
Philippos

2
@Philippos,grep -cv .还将计算仅包含不构成有效字符的字节的行。
斯特凡Chazelas

11

只是为了好玩,有些怪异sed

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

说明:

  • /./处理具有任何字符的行,因此/./!处理非空行;对于这些,H命令将它们附加到保留空间。因此,如果我们为每个空行在容纳空间中增加了一行,则总比空行数多一行。我们稍后会照顾。
  • //h空模式与最后一个正则表达式匹配,该正则表达式可以是任何字符,因此可以通过命令将所有非空行都寻址并移动到保留空间,h以将收集到的行“重置”为1。在添加下一个空行时,如预期的那样,将再次出现两个。
  • $!d停止脚本,除了最后一行以外的所有行都没有输出,因此更多命令仅在最后一行之后执行。因此,无论我们在保留空间中收集的任何空行都位于文件的末尾。好。
  • //dd仅对非空行再次执行该命令。因此,如果最后一行不为空,sed则将退出而没有任何输出。零线。好。
  • x 交易所拥有空间和图案空间,因此收集的线现在在图案空间中要处理。
  • 但是我们记得有太多行,因此我们通过用删除一个新行来减少它s/\n//
  • 瞧!行数与末尾的空行数匹配(请注意,第一行将不为空,但谁在乎),因此我们可以使用来计数wc -l

8

一些更多的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 '


6

当您实际上在寻求grep解决方案时,我添加了一个仅依赖于GNU 的解决方案grep(好的,还使用了shell语法和echo...):

#!/bin/sh
echo $(( $(grep -c "" "$1") - $(grep -B$(grep -cv . "$1") . "$1" |grep -c "") ))

我在这是要干嘛?$(grep -c ".*" "$1")计算文件中的所有行,然后我们减去文件后没有尾随的空行。

以及如何获得这些?$(grep -B42 . "$1"会grep所有非空行和它们前面的42行,因此只要不空行之前不超过42个连续的空行,它将打印所有内容直到最后一个非空行。为了避免该限制,我将其$(grep -cv . "$1")作为-B选项的参数,即空行的总数,因此始终足够大。这样,我已经删除了尾随的空行,可以|grep -c ".*"用来计算行数。

很棒,不是吗?(-;


+1,因为尽管这是可怕的代码,
但从

Grepmeister。我们不值得。
bu5hman

+1为变态。另一个(可能更快?)选项是使用tac | grep,第一个非空白-m -A 42,然后减一个。我不确定哪种方法更有效,但是您也可以wc -l | cut -d' ' -f1代替空白行呢?
Sparhawk

是的,当然,你可以做很多的事情tacwccut,但在这里我想对自己限制grep。你可以称之为反常,我称之为运动。(-;
Philippos

5

另一个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()strcoll()尽管POSIX要求使用)。
斯特凡Chazelas

@StéphaneChazelas我没考虑过$0 > ""可能与有所不同$0 != ""awk无论如何,我还是倾向于将其视为“慢”运算符(例如,如果我知道输入的数据集很大,并且处理时间很紧迫,那么我将看到我可以做些什么来减少awk必须处理的数量-我grep | awk在这种情况下使用了结构)。但是,快速浏览一下我假定的POSIX定义后,看不到对strcoll()或的任何引用memcmp()。我想念什么?
roaima '17

strcoll()== 字符串应使用特定于语言环境的整理序列进行比较。与上一版本进行比较。我就是那个提出来的人。另请参见austingroupbugs.net/view.php?id=963
斯蒂芬·查

@StéphaneChazelas一个实现,a <= b && a >= b不一定与相同a == b。哎哟!
roaima

这是GNU的情况下,awkbash(其[[ a < b ]]在GNU系统例如是en_US.UTF-8语言环境运营商)为VS 的实例(bash,没有的<>=返回对于那些真)。可以说这是在这些区域设置超过在bash / awk中定义的错误
斯特凡Chazelas

2

计算文件末尾的连续空白行数

固体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

1

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 mksh并在ksh


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.