如何从Unix文件中删除空行

时间:2013-01-28 20:19:41

标签: unix awk blank-line

我需要从输入文件中删除所有空白行并写入输出文件。以下是我的数据。

11216,33,1032747,64310,1,0,0,1.878,0,0,0,1,1,1.087,5,1,1,18-JAN-13,000603221321

11216,33,1033196,31300,1,0,0,1.5391,0,0,0,1,1,1.054,5,1,1,18-JAN-13,059762153003

11216,33,1033246,31300,1,0,0,1.5391,0,0,0,1,1,1.054,5,1,1,18-JAN-13,000603211032

11216,33,1033280,31118,1,0,0,1.5513,0,0,0,1,1,1.115,5,1,1,18-JAN-13,055111034001

11216,33,1033287,31118,1,0,0,1.5513,0,0,0,1,1,1.115,5,1,1,18-JAN-13,000378689701

11216,33,1033358,31118,1,0,0,1.5513,0,0,0,1,1,1.115,5,1,1,18-JAN-13,000093737301

11216,33,1035476,37340,1,0,0,1.7046,0,0,0,1,1,1.123,5,1,1,18-JAN-13,045802041926

11216,33,1035476,37340,1,0,0,1.7046,0,0,0,1,1,1.123,5,1,1,18-JAN-13,045802041954

11216,33,1035476,37340,1,0,0,1.7046,0,0,0,1,1,1.123,5,1,1,18-JAN-13,045802049326

11216,33,1035476,37340,1,0,0,1.7046,0,0,0,1,1,1.123,5,1,1,18-JAN-13,045802049383

11216,33,1036985,15151,1,0,0,1.4436,0,0,0,1,1,1.065,5,1,1,18-JAN-13,000093415580

11216,33,1037003,15151,1,0,0,1.4436,0,0,0,1,1,1.065,5,1,1,18-JAN-13,000781202001

11216,33,1037003,15151,1,0,0,1.4436,0,0,0,1,1,1.065,5,1,1,18-JAN-13,000781261305

11216,33,1037003,15151,1,0,0,1.4436,0,0,0,1,1,1.065,5,1,1,18-JAN-13,000781603955

11216,33,1037003,15151,1,0,0,1.4436,0,0,0,1,1,1.065,5,1,1,18-JAN-13,000781615746

8 个答案:

答案 0 :(得分:83)

sed -i '/^$/d' foo

这告诉sed删除与正则表达式^$匹配的每一行,即每个空行。 -i标志就地编辑文件,如果sed不支持您可以将输出写入临时文件并替换原始文件:

sed '/^$/d' foo > foo.tmp
mv foo.tmp foo

如果您还想删除仅由空格组成的行(不仅仅是空行),请使用:

sed -i '/^[[:space:]]*$/d' foo

编辑也会删除行尾的空格,因为显然您已经确定需要这样做:

sed -i '/^[[:space:]]*$/d;s/[[:space:]]*$//' foo

答案 1 :(得分:36)

awk 'NF' filename

awk 'NF > 0' filename

sed -i '/^$/d' filename

awk '!/^$/' filename

awk '/./' filename

NF还删除仅包含空格或制表符的行,而正则表达式/^$/则不会。

答案 2 :(得分:15)

使用grep匹配起始锚点(^)和结束锚点($)之间没有任何内容的任何行:

grep -v '^$' infile.txt > outfile.txt

如果要删除只有空格的行,您仍然可以使用grep。我在这个例子中使用Perl正则表达式,但是还有其他方法:

grep -P -v '^\s*$' infile.txt > outfile.txt

或没有Perl正则表达式:

grep -v '^[[:space:]]*$' infile.txt > outfile.txt

答案 3 :(得分:12)

sed -e '/^ *$/d' input > output

删除仅包含空格(或完全为空)的所有行。您可以将空白更改为[ \t] \t表示标签的位置。您的shell或sed是否会进行扩展会有所不同,但您可以直接键入制表符。如果您使用的是GNU或BSD sed,则可以使用-i选项就地编辑,如果这是您想要的。


  

如果我执行上面的命令仍然在输出文件中有空白行。可能是什么原因?

可能有几个原因。可能是您没有空白行,但是在行尾有很多空格,因此当您将文件捕捉到屏幕时,看起来有空行。如果这是问题,那么:

sed -e 's/  *$//' -e '/^ *$/d' input > output

新的正则表达式删除了行尾的重复空白;请参阅前面关于空白或制表符的讨论。

另一种可能性是您的数据文件来自Windows并具有CRLF行结尾。 Unix在行尾看到回车符;它不是空白,因此不会删除该行。有多种方法可以解决这个问题。一个可靠的是tr删除(-d)字符代码八进制15,又名control-M或\r或回车:

tr -d '\015' < input | sed -e 's/  *$//' -e '/^ *$/d' > output

如果这些都不起作用,那么你需要显示文件前两行的十六进制转储或八进制转储(od -c),这样我们就可以看到我们反对的内容:

head -n 2 input | od -c

根据sed -i对您不起作用的评论,您不是在使用Linux或Mac OS X或BSD - 您正在使用哪个平台? (AIX,Solaris,HP-UX作为相对合理的可能性而浮现在脑海中,但是还有很多其他不太合理的可能性。)

您可以尝试POSIX命名的字符类,例如sed -e '/^[[:space:]]*$/d';它可能会起作用,但不能保证。您可以尝试使用:

echo "Hello World" | sed 's/[[:space:]][[:space:]]*/   /'

如果有效,'Hello'和'World'之间会有三个空格。如果没有,您可能会从sed收到错误。这可能会让您在命令行上输入标签时感到悲伤。

答案 4 :(得分:8)

grep . file

grep逐行查看你的文件;点.匹配换行符之外的任何内容。因此,grep的输出是由除单个换行之外的其他东西组成的所有行。

答案 5 :(得分:5)

使用awk

awk 'NF > 0' filename

答案 6 :(得分:2)

您可以使用sed的-i选项进行就地编辑,而无需使用临时文件:

 sed -i '/^$/d' file

答案 7 :(得分:2)

要彻底删除甚至行,如果它们在perl中包含空格或制表符,则会执行以下操作:

cat file.txt | perl -lane "print if /\S/"

当然有awk和sed等价物。最好不要假设这些行完全空白,因为^$会这样做。

干杯