【问题标题】:Deleting lines in a text file based on column length - Linux [duplicate]根据列长度删除文本文件中的行 - Linux [重复]
【发布时间】:2015-12-17 23:15:22
【问题描述】:

我有一个包含如下行的大文件。 Unix中是否有sed或awk命令我可以用来删除第二列中数据长度

Query1  1041  SVTQLTNDLFQTYLRKILS*MFKVIGCSDLLGNPLTLATN*IDGVLDLVQEPWSNS*KLS  862
Query1  1707  TTSNLTWLMQKNYMRQGILQFYKVIGSSDLLGNPIGLIDKLGSGVLEFFSEPYKGLLKPG  1767
Query1  2131  TIQTLSNLIIKNYVRQGILQFYKILGSSDILGNPIGLIDNLGTGVVEFFSEPYKGMLKPG  2191
Query1  1                                                 VFEFFNEPAKGLLKPK  17

【问题讨论】:

  • 第二列表示 1041、1707、2131 还是 1?你是在检查它的长度还是它的值?另外,你尝试了什么?
  • 第二列如0,1,2所有字母和*的列
  • 这里还不清楚你想做什么。在您的示例输入中,第二列仅包含数字。你可能是指第三个?请提供更通用的示例输入以及所需的输出。
  • 该文件是上面格式的一长串行,我想删除所有第3列长度小于60的行。这里我想回来。只是前三行。

标签: linux


【解决方案1】:

下面的 AWK 脚本就可以了。

/[0-9A-Za-z]+\s+[0-9]+\s+[0-9A-Za-z*]{60,}+\s+[0-9]+/ { print($0); }

正则表达式匹配您要保留的行。如果匹配了一行,则将其打印出来。您可能需要调整正则表达式以更精确地匹配您的输入格式。我只是从你展示的几个例子中推断出我可以推断出的模式。

正则表达式解释:

  • [0-9A-Za-z]+ 一个或多个字母数字字符
  • \s+ 一个或多个空格
  • [0-9]+ 一位或多位数字
  • \s+一个或多个空格
  • [0-9A-Za-z*]{60,}+ 六十个或更多字母数字字符和星号
  • \s+一个或多个空格
  • [0-9]+ 一位或多位数字

另一种选择是使用

/./ { if (length($3) >= 60) print($0); }

假定所有行都采用给定的列格式。它匹配任何行,如果第三列足够宽,则有条件地打印它。

在 AWK 中,$<i>N</i> 指的是当前行的第 N 列,$0 指的是整行。默认情况下,列在空白处拆分。

正如fedorqui 在评论中指出的那样,语法越简洁

length($3) >= 60

可以用来达到与 AWK 的默认行为相同的效果,即如果条件为真,则打印当前行。我从来没有碰巧记得在 AWK 中可以使用的所有快捷方式……

【讨论】:

  • awk 'length($3)&gt;=60' file 就足够了:如果这个条件的计算结果为真,awk 的默认行为将完成剩下的工作:只要有东西为真,它就会打印当前行。
  • 是的,效果很好!
  • @fedorqui 好点,我会把它添加到答案中。
  • 这同样适用于/regex/ {print ($0)}/regex/ 一个人就够了。
  • @fedorqui 感谢您找到骗子。我很天真地认为以前已经有人问过这个问题。鉴于欺骗中已经提出了简洁的解决方案,您认为我应该删除我的答案吗?
【解决方案2】:

Perl 解决方案:

perl -ane 'print unless 60 > length $F[2]' file
  • -n逐行读取输入
  • -a 将每一行拆分为空白处的 @F 数组

【讨论】:

    猜你喜欢
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-07
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    相关资源
    最近更新 更多