【问题标题】:How to delete all lines of a text file that contain ./如何删除包含 ./ 的文本文件的所有行
【发布时间】:2021-06-10 21:43:39
【问题描述】:

我的文本文件中的数据看起来像这样

chrom start end gene mutation
chr1 12756 12790 DVL1 T/C
chr1 12856 12890 DVL2 ./.
chr1 12956 12990 DVL3 T/C

我需要删除所有包含 ./ 的行。其中,文件大约有 500 行,所以我不需要任何超级高效的东西。

我尝试了很多不同的方法,但都没有成功,都是为了去掉“./”。并删除不包含“./.”的行在最后一列。

grep -v "./." input.txt > output.txt

awk '/"./."/' input.txt > tmpfile && mv tmpfile output.txt

fgrep -xv "./." input.txt > output.txt

awk -F',' '$5 !~ "./." {print $0}' input.txt > output.txt

awk 'BEGIN { OFS=FS="\t" } $5 !~ /^('./.')/' input.txt > output.txt

awk '!"./." ' input.txt > output.txt

sed -i '"./."d' input.txt > output.txt

我觉得我很接近,但看不到我缺少什么,感谢任何帮助。

【问题讨论】:

  • grep -v '\./\.',避开点。或使用grep -vF './.' 。见ideone.com/IcjM5Z
  • @RavinderSingh13 关于转义特殊字符的唯一问题,一个点。或使用-F 选项。该帖子中涵盖了所有内容。一般来说,What special characters must be escaped in regular expressions? 的骗子,但我试图在这里找到一个面向grep 的帖子
  • @WiktorStribiżew,我同意有些事情被涵盖了,但是当我们有一个完整的答案时,为什么要进行部分欺骗。如果我们放一个精确的骗子来制造这个骗子,我很好。
  • 根据您对输入文本外观的艺术渲染,我们无法判断哪些是正确的。如果输入以逗号分隔,awk -F ',' 将起作用; awk -F '\t' 是正确的,如果它是制表符分隔的。如果您使用了正确的正则表达式,其中任何一个都应该有效,但如果没有更多细节,我们无法判断。
  • edit 您的问题会显示简洁、可测试的纯文本示例输入和预期输出,以便我们为您提供帮助。没有图片,没有链接,没有艺术表格,只有原始文本,我们可以按原样复制/粘贴以测试潜在的解决方案。

标签: bash awk sed grep


【解决方案1】:

使用这个简单的grep,只需使用-v 选项来忽略给定的模式行。

grep -v '\./\.' Input_file

或在awk 中尝试以下操作:

awk '$NF=="./."{next} 1' Input_file

【讨论】:

    【解决方案2】:

    我们无法从您的输入数据中看出您的输入文件是什么样的。如果它是制表符分隔的,则告诉 awk 在制表符上拆分:

    awk -F '\t' '$5 != "./."' input.txt >output.txt
    

    如果你有一个逗号分隔的输入文件,相应的命令应该是这样的

    awk -F ',' '$5 != "./."' input.txt >output.txt
    

    != 字符串不等价运算符比这里的正则表达式更易于使用。我们只是说“打印第五列不完全是这个字符串的行。”

    对应的正则表达式看起来像

    awk -F ',' '$5 !~ /^\.\/\.$/' input.txt >output.txt
    

    但您显然希望在此处避免使用 leaning toothpicks syndrome

    再详细一点,

    • grep -v "./." 是错误的,因为它删除了任何带有斜线的行,并且两边都带有任何字符。您可以通过使用反斜杠或字符类转义点来解决此问题; grep -v '\./[.]' 演示了两者。这仍然是错误的,因为它在任何地方寻找模式,而不仅仅是在最后一个字段中;但如果您不期望在其他领域有匹配,也许这已经足够了。

    • awk '/"./."/' 查找两边用双引号括起来的斜线,中间有任何字符。

    • fgrep -xv "./." 在其他方面很好,但 -x 选项将表达式限制为仅匹配不包含任何其他内容的行。

    • awk -F',' '$5 !~ "./." {print $0}' 如果您修复了正则表达式,它将适用于逗号分隔的文件。 { print $0 } 是多余但无害的。

    • awk 'BEGIN { OFS=FS="\t" } $5 !~ /^('./.')/' 对制表符分隔的文件有一定的承诺,但正则表达式是无可救药的拙劣。正则表达式中的单引号是错误的,但不会破坏脚本的语法;它们基本上会在 Awk 处理脚本之前消失,因为引号是由 shell 处理的……长话短说,请阅读 shell 引用。

    • awk '!"./." ' 不会做任何事情;它说如果条件中的静态字符串为空,则打印,但事实并非如此。

    • sed -i '"./."d' input.txt > output.txt 是错误的,因为-i 选项将对input.txt 进行更改,并且不会将任何内容打印到标准输出;由于引用问题和需要被有效的正则表达式分隔符包围,正则表达式存在缺陷。 sed '/\.\/\./d' input.txt > output.txt 的工作方式与上面的第一个 grep 示例类似。

    【讨论】:

      猜你喜欢
      • 2015-07-15
      • 1970-01-01
      • 2017-08-20
      • 2018-06-28
      • 2018-08-31
      • 2020-07-02
      • 2013-11-04
      • 1970-01-01
      相关资源
      最近更新 更多