【问题标题】:How to remove blank lines from a Unix file如何从 Unix 文件中删除空行
【发布时间】:2013-01-12 06:58:22
【问题描述】:

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

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

【问题讨论】:

  • 这是我的示例数据,以下任何命令都不适合我。 :(
  • 他们没有工作因为你问错了问题。你真的试过sed -i '/^[[:space:]]*$/d' foo吗?因为如果这不起作用,那么您需要重申问题
  • @SOaddict,我在这里看到多个答案可以回答您的原始问题以及处理“空白”行中的空格的问题。如果这些不起作用,我认为您需要检查输入文件并更新问题。
  • 我复制粘贴了准确的输入文件示例。
  • 下面的命令(应该工作)似乎不起作用的一个可能原因是文件源自 Windows 或通过 Windows 机器传输,实际上有 CRLF(回车,换行)结尾Unix 风格的 NL(换行符,又名 LF)行尾。 Unix 工具将 CR 视为另一个字符,因此像 /^$/ 这样的正则表达式将无法匹配带有 CRLF 结尾的空行。使用 sed -i '/^[[:space:]]*$/d;s/[[:space:]]*$//' 的版本也应该适用于 CRLF 行; /^[[:space:]]*$/ 模式匹配行中的 CR。

标签: unix awk blank-line


【解决方案1】:

使用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

【讨论】:

  • 我的 op 文件中仍然有空格。
【解决方案2】:

您可以 sed 的 -i 选项在不使用临时文件的情况下就地编辑:

 sed -i '/^$/d' file

【讨论】:

  • 那么这些行不是“空白”行。 Jonathan Wakely 也回答了如何删除空格。不行吗?
  • 你能清楚地描述一下空白行到底是怎么回事吗?
  • 我的第 19 列有空格。所以我想我应该先删除空格,然后执行这些命令中的任何一个..
  • 没有。 sed -i '/^[[:space:]]*$/d' file 应该删除所有带有任何空格的行,例如 或这些的任意组合。
  • 命令中没有语法错误。您是否像我之前的评论中那样exacty 使用它?你能复制粘贴你使用的确切命令吗?
【解决方案3】:
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

【讨论】:

  • 我考虑过这种可能性,所以写了“如果你的 sed 不支持那个”部分。似乎至少有七个人浪费了时间来帮助您,而您要么没有阅读,要么没有正确思考。
  • 错误信息:sed: 非法选项 --i 用法:sed [-n] [-e script] [-f source_file] [file...]
  • 这是我的坏乔纳森。你的回答是对的。从昨天开始就没有再检查了。
  • 任何在 Mac 上使用 -i 选项有问题的人:改用 -i .bak(如 sed -i .bak '/^[[:space:]]*$/d' foo。我们拥有的 sed 版本希望在就地操作时使用文件扩展名编辑。所以传递-i .bak 告诉它复制现有文件,扩展名为.bak,如果就地编辑失败,您可以恢复。
  • 请注意,GNU sed 中的 -i 选项也接受备份后缀作为可选参数,因此如果您编写 -i.bak 时将选项和参数联系起来,代码将同时适用BSD (Mac OS X) sed 和 GNU sed。 Mac OS X 需要备份后缀,并允许将其与-i 选项分开。标准:如此美妙的事情……
【解决方案4】:
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 不适合您的 cmets 判断,您不是在 Linux、Mac OS X 或 BSD 上工作——您在哪个平台上工作? (AIX、Solaris、HP-UX 是相对合理的可能性,但也有很多其他不太合理的可能性。)

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

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

如果有效,“Hello”和“World”之间将有三个空格。如果没有,您可能会收到来自sed 的错误。这可能会让您不必担心在命令行上输入标签。

【讨论】:

  • 如果我执行上述命令,我的输出文件中仍然有空行。可能是什么原因?
  • 可能你的“空白”行不是空的,它们包含空格。有关删除由 any 空格 组成的行的解决方案,请参阅我的答案
  • 是的,好像有空格。如何删除行尾的空格?
  • 哦,FFS,如果你问错问题,没人能正确回答!
【解决方案5】:

要彻底删除行 即使 如果它们包含空格或制表符,在 perl 中类似这样的东西会这样做:

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

当然还有 awk 和 sed 等价物。最好不要像^$ 那样假设这些行完全是空白的。

干杯

【讨论】:

    【解决方案6】:
    grep . file
    

    grep 逐行查看您的文件;点. 匹配任何除了换行符。因此,grep 的输出是所有由单个换行符以外的内容组成的行。

    【讨论】:

    • 如果“空白”行包含空格,您可以使用grep '[^[:space:]]' file
    • 19个字的解释真的太多了吗?
    • @JoshCaswell 这毫无意义。就像当您阅读“i = 0”的代码并且有人添加注释“将变量 i 设置为零值”时,因为有时有人告诉他们在代码中添加 cmets 是个好主意。在这种情况下,grep 命令的作用非常明显,或者 OP 真的需要阅读手册页。
    • 关于您的帖子太短的复制粘贴错误消息没有意义?我们对“无意义”有不同的定义。
    • 不是没有意义,同样没有意义,但更多的努力。在一个完美的世界中,网站根本不需要最少的字符数,那么我们就不会进行这种毫无结果的讨论。
    【解决方案7】:

    使用 awk

    awk 'NF &gt; 0' filename

    【讨论】:

    • awk 'NF' 一个人就够了。
    【解决方案8】:
    awk 'NF' filename
    

    awk 'NF > 0' filename
    

    sed -i '/^$/d' filename
    

    awk '!/^$/' filename
    

    awk '/./' filename
    

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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    相关资源
    最近更新 更多