我有一个文件末尾有空行的文件。我可以使用grep
文件名作为脚本中的变量传递来计算文件末尾的空白行数吗?
答案1
如果空行是仅有的在最后
grep -c '^$' myFile
或者:
grep -cx '' myFile
答案2
只是为了好玩,有些令人毛骨悚然sed
:
#!/bin/sh
sed '/./!H;//h;$!d;//d;x;s/\n//' "$1" | wc -l
解释:
/./
寻址具有任何字符的行,因此/./!
寻址空行(例如/^$/
,但我想重用相反的模式);对于这些,该H
命令将它们附加到保留空间。因此,如果我们为每个空行添加一行到保留空间,则总是比空行的数量多一行。我们稍后会关心这个。//h
空模式匹配最后一个正则表达式,它是任何字符,因此任何非空行都会被寻址并且搬家了通过命令将收集的行“重置”为 1 到保留空间h
。当附加下一个空行时,如预期的那样,将再次出现两行。$!d
停止脚本,除了最后一行之外的每一行都没有输出,因此仅在最后一行之后执行进一步的命令。因此,我们在保留空间中收集的任何空行都位于文件的末尾。好的。//d
:d
仅对非空行再次执行该命令。因此,如果最后一行不为空,sed
将退出且没有任何输出。零线。好的。x
交换保存空间和模式空间,因此收集的行现在位于模式空间中以进行处理。- 但我们记得一行太多了,所以我们通过用 删除一个换行符来减少它
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。
POSIXly:
awk 'NF{n=NR};END{print NR-n}' < file
但这意味着完整读取文件(tail -r
/tac
将从可查找文件的末尾向后读取文件)。这给出1
了 的输出printf 'x\n '
。
答案4
因为你实际上是在要求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 ".*"
计算行数。
太棒了,不是吗? (-;