【问题标题】:Remove lines containing space in unix在 unix 中删除包含空格的行
【发布时间】:2013-12-15 19:06:19
【问题描述】:

下面是我的逗号分隔的 input.txt 文件,当任何 1 列有空格时,我想读取列并将行写入 output.txt。

input.txt的内容:

1,Hello,world
2,worl d,hell o
3,h e l l o, world
4,Hello_Hello,World@c#
5,Hello,W orld

output.txt的内容:

1,Hello,world
4,Hello_Hello,World@c#

使用awk 无法实现?请帮忙!

【问题讨论】:

  • grep -v 可以正常工作时,为什么还要使用awk
  • is't - 今年我见过的最奇怪的拼写错误。我发誓。
  • 在收到多个实质性答案后,用改变游戏规则的附加要求来更新问题并不是好的形式。我很想建议恢复编辑,接受答案并发布新问题。
  • @minitech 我知道(看过 Twitter?),但我仍然认为这是一个错误。说真的。

标签: linux shell unix sed awk


【解决方案1】:

过滤带空格的行的一种简单方法是使用grep的反向匹配:

grep -v ' ' input.txt 

如果您必须使用awk

awk '!/ /' input.txt 

perl:

perl -ne '/ / || print' input.txt 

或者纯bash

while read line; do [[ $line == *' '* ]] || echo $line; done < input.txt
# or
while read line; do [[ $line =~ ' ' ]] || echo $line; done < input.txt

更新

要检查字段 2 是否包含空格,您可以像这样使用awk

awk -F, '$2 !~ / /' input.txt

检查字段 2 或字段 3 是否包含空格:

awk -F, '!($2 ~ / / || $3 ~ / /)' input.txt

关于您在 cmets 中的后续问题

sed做同样的事情,我只知道这些尴尬的解决方案:

# remove lines if 2nd field contains space
sed -e '/^[^,]*,[^,]* /d' input.txt 
# remove lines if 2nd or 3rd field contains space
sed -e '/^[^,]*,[^,]* /d' -e '/^[^,]*,[^,]*,[^,]* /d' input.txt 

关于您在 cmets 中的第二个后续问题

忽略第二个或第三个字段中的前导空格:

awk -F', *' '!($2 ~ / / || $3 ~ / /)' input.txt
# or perhaps what you really want is this:
awk -F', *' -v OFS=, '!($2 ~ / / || $3 ~ / /) { print $1, $2, $3 }' input.txt

【讨论】:

  • 你不需要 { print } 因为它是 awk 的默认操作。
  • 感谢@Jason 提供awk。如何更改awk 以便仅检查一两个字段?
  • awk -F, '$2 !~ / /' 5,Hello,W orld 失败,因为您只测试两个字段,并且有多个 two
  • 感谢 @janos 在 awk 中的 OR。可以使用 sed 编写相同的命令吗?只是好奇
  • @janos this cmd '$2 !~ / /' 也在考虑前导和尾随零。无论如何要删除它们?
【解决方案2】:

这也可以通过轻松完成

sed '/ /d' input.txt

【讨论】:

  • 谢谢,但我的问题是,我想检查一个特定的列。我错过了在问题中添加它。
【解决方案3】:

试试这个单线

awk 'NF==1' file

正如@jwpat7 指出的那样,如果该行只有前导空格,则不会给出正确的输出,那么这条带正则表达式的行应该可以,但它已经发布在 janos 的回答。

awk '!/ /' file

awk -F' *' 'NF==1'

【讨论】:

  • 如果这行得通,我会 +1 ...但是当取消资格的空格位于行的前面时,它会失败
  • 相当整洁,但相当晦涩。 awk 在空白处拆分并将NF 设置为字段数;如果是 1,则没有可拆分的空格。
  • @jwpat7 你是对的,当然;但 OP 的示例表明这可能不是问题。
【解决方案4】:

纯 bash 的乐趣...

#!/bin/bash

while read line
do
    if [[ ! $line =~ " " ]]
    then
        echo $line
    fi
done < input.txt

【讨论】:

    【解决方案5】:
    columnWithSpace=2
    ColumnBef=$(( ${columnWithSpace} - 1 ))
    
    sed '/\([^,]*,\)\{${ColumnBef\}[^ ,]* [^,]*,/ d'
    

    如果您直接知道该列(例如 3):

    sed '/\([^,]*,\)\{2}[^ ,]* [^,]*,/ d'
    

    【讨论】:

      【解决方案6】:

      如果您可以相信输入始终不超过三个字段,只需在逗号后的某个位置找到一个空格就足够了。

      grep ',.* ' input.txt
      

      如果可以(或通常有)更多字段,您可以使用grep -E 和合适的ERE 来实现,但您很快就会接近等效的 Awk 解决方案更具可读性和可维护性的点.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-03-22
        • 2019-09-28
        • 2023-03-11
        • 2015-06-01
        • 1970-01-01
        • 2020-12-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多