答案1
您可以使用以下代码查找空行及其行号:
grep -E --line-number --with-filename '^$' file.txt
一个例子:
w3@aardvark:~(0)$ grep -E --line-number --with-filename '^$' file.txt
file.txt:1:
file.txt:3:
file.txt:4:
w3@aardvark:~(0)$ cat -n file.txt
1
2 Not empty
3
4
5 Not empty
w3@aardvark:~(0)$
如果“空”行包含空格或 TAB,请使用:
grep -E --line-number --with-filename '^\s*$' file.txt
答案2
sed
将使用命令报告行号=
,因此您可以使用此表达式来报告空行(^
(行首)和$
(行末)之间没有任何内容的行)的行号:
sed -n '/^$/=' file
我们使用该-n
选项来抑制打印流(当我们使用时,行号与行本身分开打印=
,所以这里没有p
命令),所以唯一的输出是匹配行的行号。
$ sed -n '/^$/=' foo
1
3
5
7
(如果第 1、3、5 和 7 行是空的foo
)
以下示例展示了如何获得所需的用户交互。您可以使用任何解决方案代替sed
这些结构中的表达式...
$ cat foo
2
4
6
8
所以:
$ read -p "Enter file name: "; echo -e "The following lines are empty in "$REPLY":\n$(sed -n '/^$/=' "$REPLY" | tr '\n' ' ')"
Enter file name: foo
The following lines are empty in foo:
1 3 5 7
(使用tr '\n' ','
逗号代替空格)
您可以保存为脚本(我将其命名为empline
):
#!/bin/bash
read -p "Enter file name: "
echo -e "The following lines are empty in "$REPLY":\n\
$(sed -n '/^$/=' "$REPLY" | tr '\n' ' ')"
使脚本可执行:
chmod u+x empline
然后你可以像这样运行它
$ ./empline
Enter file name: foo
The following lines are empty in foo:
1 3 5 7
您可以跳过该read
行并替换"$REPLY"
为"$1"
以使用文件名作为位置参数(因此运行./empline foo
)。为了简化使用,您可以创建一个函数并将其添加到~/.bashrc
:
function empline() {
echo -e "The following lines are empty in "$1":\n\
$(sed -n '/^$/=' "$1" | tr '\n' ' ')"
}
这将文件名作为参数:
$ empline foo
The following lines are empty in foo:
1 3 5 7
答案3
使用awk
方法多文件输入(见文章末尾)是最强大的。
单个文件输入:
awk 'BEGIN { printf "Line numbers of empty lines in " ARGV[1] ": " } !NF { printf sep NR ; sep="," } END { printf "\n" }' file.txt
该BEGIN
部分在处理输入文件之前运行。
ARGV[1]
是输入文件的名称。这对应于 awk 的FILENAME
变量,该变量在本节中不起作用BEGIN
。
!NF
匹配空白行或仅包含字段分隔符的行。默认字段分隔符是空格和制表符,因此仅包含空格和制表符的行将被视为空行。 NF
(不带感叹号)匹配以下行包含数据,并添加!
倒置比賽。
NR
是当前正在评估的输入文件的行号。 NR
如果在命令行上指定了额外的输入文件,则不会重置为 1。
为了防止逗号出现在第一个匹配的行号前面,请sep
在打印第一个匹配项之后才定义字符串。
该END
部分在处理输入文件后运行。在此示例中,它通过打印 Unix 样式的换行符干净地终止输出。
示例输出:
Line numbers of empty lines in file.txt: 8,13,15,20,25,28
在没有先设置字符串名称的情况下使用它有点草率,即使你最初想为空。您可以sep
在以下部分中明确将字符串设置为空BEGIN
:
awk 'BEGIN { sep="" ; printf "Line numbers of empty lines in " ARGV[1] ": " } !NF { printf sep NR ; sep="," } END { printf "\n" }' file.txt
多文件输入:
awk 'FNR==1 && NR>1 { printf "\n" } FNR==1 { sep="" ; printf "Line numbers of empty lines in " FILENAME ": " } !NF { printf sep FNR ; sep="," } END { printf "\n" }' file1.txt file2.txt file3.txt
FNR
类似于NR
,不同之处在于FNR
行号计数器在每个文件开始时重置为 1。
该部分FNR==1 && NR>1 { printf "\n" }
使每个文件的输出打印在单独的行上。当每个文件的第一行额外的处理输入文件,但不会处理第一行第一的文件。
示例输出:
Line numbers of empty lines in file1.txt: 8,13,15,20,25,28
Line numbers of empty lines in file2.txt: 1,2,4,6,7,9,10
Line numbers of empty lines in file3.txt: 3,8,9,11,13,15
答案4
perl
:
如果行号为空 ( ),则打印 ( printf("%s\n", $.)
) 行号:if /^$/
perl -ne 'printf("%s\n", $.) if /^$/' file.txt
python3
:
遍历start == 1
文件的枚举()行,并在空时打印行号:
with open('file.txt') as f:
for idx, line in enumerate(f, 1):
if line.rstrip('\n') == "":
print(idx)