使用sed删除空行


349

我正在尝试使用sed删除空行:

sed '/^$/d'

但我没有运气。

例如,我有以下几行:

xxxxxx


yyyyyy


zzzzzz

我希望它像:

xxxxxx
yyyyyy
zzzzzz

这应该是什么代码?


2
您的sed命令看起来不错,它应该可以工作
Perreal

即使您没有空格/制表符,但CR + LF行尾,上述命令也不起作用。
devnull

Answers:


626

您的“空”行中可能有空格或制表符。使用POSIX类sed去除只含有空格的所有行:

sed '/^[[:space:]]*$/d'

使用ERE的较短版本,例如gnu sed:

sed -r '/^\s*$/d'

(请注意,sed的确实支持PCRE)。


3
@HuStmpHrrr gnu sed根本不支持PCRE。与ERE-r
肯特,

8
需要OS X sed -i "" '/^[[:space:]]*$/d' <filename>
jww

@BernieReiter ^\s*$将匹配所有“空”行,此处为空表示行不包含任何字符,或者行仅包含空字符串(例如空格)。使用d命令sed将删除所有匹配的行。
肯特,

96

我缺少awk解决方案:

awk 'NF' file

哪个会返回:

xxxxxx
yyyyyy
zzzzzz

这是如何运作的?由于NF代表“字段数”,因此那些空行具有0个字段,因此awk会将0评估为False,并且不打印任何行;但是,如果至少有一个字段,则评估结果为True,并awk执行其默认操作:打印当前行。


1
哇。甚至与BSD的awk的“最小化”版本一起运行(版本20121220(FreeBSD)。谢谢:-)
Bernie Reiter

@BernieReiter,欢迎您:)是的,这是所有awk版本都允许的非常基本的习惯用法。
fedorqui'SO停止伤害

而且它要快得多,尽管-为了进行快速又肮脏的测试-我两次调用awk: $ time (topic companies <data.tpx | awk 'NF' - | awk -f dialog_menu.awk -) real 0m0.006s user 0m0.000s sys 0m0.008s $ time (topic companies <data.tpx | gsed '/^\s*$/d' | awk -f dialog_menu.awk -) real 0m0.014s user 0m0.002s sys 0m0.006s 您是否知道将其包含在awk脚本(例如模式)中的巧妙方法?awk'/ mypattern / {do stuff ...}'
伯尼·瑞特

你可以说@BernieReiter awk 'NF {do stuff...}'
fedorqui'SO停止伤害

1
请注意,这也将仅忽略带有空格的行。
wisbucky

60

sed '/^$/d'应该没问题,您是否希望在适当位置修改文件?如果是这样,则应使用该-i标志。

也许这些行不是空的,所以如果是这种情况,请看以下问题:从txtfiles中删除空行,从行首和行尾删除空格,我相信这就是您要实现的目标。


是。我正在修改文件。* .csv。-i应该如何放置到sed命令中?
乔纳斯(

2
sed -i '/^$/d'是做到这一点的一种方法。
阿尔贝托·扎卡尼

49

1
这些正确地显示在您的在线工具,但[]应该不是在括号表达式进行转义,所以这里的代码是不正确的\[\[:space:\]\]\[ \t\]-应[[:space:]][ \t]
本杰明·

1
@BenjaminW。感谢您抓住这一点。这些不是来自原始作者,而是来自Edit 3,当时它从常规文本更改为“代码”,然后“暴露”了\转义。我已经修复了它们。
wisbucky

30

我相信这是最简单,最快的方法:

cat file.txt | grep .

如果您还需要忽略所有空白行,请尝试以下操作:

cat file.txt | grep '\S'

例:

s="\
\
a\
 b\
\
Below is TAB:\
    \
Below is space:\
 \
c\
\
"; echo "$s" | grep . | wc -l; echo "$s" | grep '\S' | wc -l

输出

7
5

5
无需catgrep需要的文件,以及:grep . file.txt
西罗桑蒂利郝海东冠状病六四事件法轮功

3
是的,我知道,但是最初的问题没有提到源文件是文件还是其他文件,因此解决方案是在“ |”之后以及源文件之前的内容。只是为了从线源中区分解决方案。
瓦迪姆

2
grep '\S'绝对不是便携式的。如果可以,grep -P则可以使用,grep -P '\S'但也不是所有平台都支持。
三胞胎

grep .与其他解决方案相比,它的缺点是它将所有文本突出显示为红色。其他解决方案可以保留原始颜色。比较unbuffer apt search foo | grep .unbuffer apt search foo | grep -v ^$
wisbucky

15

这里接受的答案和上面接受的答案的帮助下,我使用了:

$ sed 's/^ *//; s/ *$//; /^$/d; /^\s*$/d' file.txt > output.txt

`s/^ *//`  => left trim
`s/ *$//`  => right trim
`/^$/d`    => remove empty line
`/^\s*$/d` => delete lines which may contain white space

这涵盖了所有基础,并且完全可以满足我的需求。赞扬原始海报@Kent和@kev


5

你可以说:

sed -n '/ / p' filename    #there is a space between '//'

..这意味着print all lines except the empty one(s)安静
Timo

2

您也可以使用“ grep”执行类似的操作:

egrep -v "^$" file.txt


2

由于您的文本文件是在Windows上创建的,因此您很可能会看到意外的行为,因此行尾的顺序为\r\n。您可以在运行sed或使用sed之前使用dos2unix将其转换为UNIX样式的文本文件。

sed -r "/^\r?$/d"

删除空行,无论是否有回车。


嗨,-r标记的作用是什么,是否可以将其与-i直接修改文件并避免打印到屏幕上。此外,我认为此命令也将适用于sed -r "/^\r$/d"
Alexander Cska

2

另一种选择无sedawkperl,等

strings $file > $output

字符串-打印文件中可打印字符的字符串。


你的意思strings不是string
Mickael B.

嗨@MickaelB。您说得对,我已解决。
user319660

0

我的bash特定答案是建议为此使用perl带有全局模式g标志的替换运算符,如下所示:

$ perl -pe s'/^\n|^[\ ]*\n//g' $file
xxxxxx
yyyyyy
zzzzzz

该答案说明了如何解释空行中是否有空格([\ ]*),以及|如何分隔多个搜索字词/字段。在macOS High Sierra和CentOS 6/7上进行了测试。

仅供参考,OP的原始代码在macOS High Sierra和CentOS 6/7 Linux的高性能超级计算集群上的Terminal中运行sed '/^$/d' $file正常bash


-3

对于具有sed的 FreeBSD 10.1而言,我只能使用以下解决方案:

sed -e '/^[     ]*$/d' "testfile"

里面[]有空格和制表符。

测试文件包含:

fffffff next 1 tabline ffffffffffff

ffffffff next 1 Space line ffffffffffff

ffffffff empty 1 lines ffffffffffff

============ EOF =============
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.