【问题标题】:How to remove the lines with fewer columns in a tab separated text file?如何删除制表符分隔的文本文件中列较少的行?
【发布时间】:2017-05-09 23:15:19
【问题描述】:

我有一个包含 11 列的制表符分隔的文本文件(对于某些行,某些列的值包括空值)。有些行的列较少。我想删除列较少的行。我该怎么做?

【问题讨论】:

标签: bash text awk sed grep


【解决方案1】:

听起来您可以只使用 awk 过滤掉 NF 不是 11 的行:

awk -F'\t' 'NF == 11' file

【讨论】:

  • 如果 NF==11 只是制表符分隔的空字段,它们是否有效? OP 在他之前的类似问题中提供了类似的输入。
  • @Inian 因为输入字段分隔符已更改为单个选项卡,空字段仍然计数。如果使用了FS,则多个连续的空白字符将被视为单个字段分隔符。
  • 但这是否将输出字段分隔为单个选项卡?
  • 不接触字段,所以11个字段的行不会被修改。我没有看到上一个问题,但如果假设有一些先验知识,那么应该编辑这个问题。
  • stackoverflow.com/a/41313768/5291015,是我对类似 OP 的回答,他“不接受”声称其中包含空字段且不适用于 NF==10 条件的答案?如果我在这里遗漏了一些东西,请告诉我。
【解决方案2】:

如果您有一个制表符分隔的文件,例如:

$ cat foo
1       2       3
4               6
7

或更生动地:

1\t2\t3
4\t\t6
7\t\t

每条记录的字段数仍为 3:

$ awk -F'\t' '{print NF}' foo
3
3
3

如果要打印没有空字段的记录:

$ awk -F'\t' '{for(i=1;i<=NF;i++) if($i=="") next}1' foo
1       2       3

【讨论】:

  • 在我的文件中,大多数行都有 11 列,但其中一些实际上有 10 列(我不是在谈论空值,这两行都可能包含一些空值)。如何删除列数较少的行?
  • 使用@TomFenech 的解决方案。这不适合你吗?
【解决方案3】:

此 Perl 代码完全符合您的要求:

a) 它会忽略字段数不等于我们想要的行数

b) 它忽略具有空字段的行

#!/usr/bin/env perl
my ($fields, $f, $n, $size);
my $NUM_FIELDS = 11;
while (<STDIN>) {
  chomp;
  @fields = split(/,/, $_);
  next if $#fields + 1 != $NUM_FIELDS;
  $n = 0;
  foreach $f (@fields) {
    break if length($f) == 0;
    $n++;
  }
  printf("%s\n", $_) if ($n == $NUM_FIELDS);
}

【讨论】:

  • 我不想忽略空值的行!几乎所有的行都有一些空值。我只想忽略列数少于其他行的行。我想修改文件。
【解决方案4】:

这可能对你有用(GNU sed):

sed 's/[^\t]\+/&/11;t;d' file

这会将第十一个非制表符替换为自身或删除该行。

【讨论】:

    猜你喜欢
    • 2017-05-09
    • 2023-04-07
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-10
    • 2020-03-28
    • 1970-01-01
    相关资源
    最近更新 更多