【问题标题】:Replace all the text in all columns except the last替换除最后一列之外的所有列中的所有文本
【发布时间】:2013-11-11 11:24:27
【问题描述】:

我有一个读取的数据文件

field1 field2 diseased 
discrete discrete   discrete                                                    
                    class
No Yes No 
Yes Yes Yes
No No No

我想用问号 (?) 替换除最后一列之外的所有列中的否。这只是一个包含三列的玩具示例,我有数千列的数据。所以,单独做是没有意义的。前三行也是标题,我希望它们保持原样。所以我希望我的结果是

field1 field2 diseased 
discrete discrete   discrete                                                    
                    class
? Yes No 
Yes Yes Yes
? ? No

我想在不更改文件格式的情况下执行此操作。到目前为止,我可以通过删除最后一列并替换 No 并再次附加最后一行来做到这一点,但这会丢失格式。也感谢您的帮助。 在某些情况下,当有大量“是”且最后一列为“否”时,最后会添加一些选项卡。命令

cat -e test 

结果

field1 field2 diseased 
discrete discrete   discrete                                                    
                    class
? Yes No$
Yes Yes Yes
? ? No
Yes Yes No $

我不想在最后一个 No 和 $ 之间有空格

【问题讨论】:

    标签: perl bash shell unix awk


    【解决方案1】:

    像这样,例如:

    $ awk 'BEGIN{OFS=FS="\t"} {for (i=1; i<NF; i++) if ($i=="No") $i="?"}1' a
    ?       Yes     No 
    Yes     Yes     Yes
    ?       ?       No
    

    它从第一个到倒数第二个字段进行检查,并在必要时进行替换。

    BEGIN{OFS=FS="\t"}用于设置输入输出字段分隔符为制表符。

    【讨论】:

    • 有趣的是,我的文件是制表符分隔的,它变成了空格分隔的文件。但问题是,如果所有列中都有“是”,则制表符分隔的文件会保留。有没有简单的方法来解决这个问题??
    • @lovedynasty BEGIN {FS=OFS="\t"}
    • @jkshah wow,当我看到你的评论时正在更新这个,呵呵
    • @lovedynasty 除非您给出适当的解释,否则我不会继续关注这一点。请注意 anubhava 和我,我们正在检查它,您从一个答案转到另一个答案,试图在没有正确解释的情况下弄清楚事情。
    • 对不起,来源有问题......在其他情况下没有,但在所有是的情况下都有。对不起 !!现在可以了
    【解决方案2】:

    除非您有其他一些可能与No 匹配的标头,否则您应该使用一些非常简单的东西,例如:

    perl -pwe 's/\bNo\b(?!\s*$)/?/g' infile > outfile
    

    这将替换所有带有单词边界的No 字符串。 Shell 重定向会将输出存储在一个新文件中。您也可以使用-i 开关,但我通常不向新用户推荐它。

    使用否定的前瞻断言来确保它不是该行的最后一个匹配项。

    【讨论】:

    • 不产生所需的输出。甚至在最后一列中替换。
    • 啊哈,我没看到。嗯,这很容易解决。
    【解决方案3】:

    使用 awk:

    awk -v ccol=3 '{for (i=1; i<=NF; i++) if (i != ccol && $i=="No") $i="?"} 1' OFS='\t' file
    

    您可以为ccol 传递任何值以跳过要替换的列。

    【讨论】:

    • 有趣的是,我的文件是制表符分隔的,它变成了空格分隔的文件。但问题是,如果所有列中都有“是”,则制表符分隔的文件会保留。有没有简单的方法来解决这个问题??
    • 是的,现在查看编辑后的命令,它使用OFS='\t' 使输出制表符分隔。
    • @lovedynasty:当然,这个 awk 命令并不假定只需要跳过最后一列,因为您可以将 col # 作为参数传递。
    • 如果有一列全是赞,最后一列是否,它会在否之后添加一个选项卡。否则,没问题。有什么办法解决这个问题吗?是 是 是 否 否 是 否 否 cat -e 文件会产生 是 是 是 否 $ ?是的 ?没有$
    • 让我试着解决这个问题。
    【解决方案4】:

    这里我认为最后一列不能被替换(如果需要,这可以很容易地调整)。

    使用 awk :

    [ ~]$ awk '{for (i=1;i<NF;i++){if ($i=="No"){$i="?"}}; print $0}' test.txt 
    field1 field2 diseased 
    discrete discrete   discrete                                                    
                        class
    ? Yes No
    Yes Yes Yes
    ? ? No
    

    使用 sed :

    [ ~]$ sed "s/No/\?/g; s/\?\ *$/No/g" test.txt 
    field1 field2 diseased 
    discrete discrete   discrete                                                    
                    class
    ? Yes No
    Yes Yes Yes
    ? ? No
    

    【讨论】:

      【解决方案5】:

      另一个awk

      awk '$1=="No" {$1="?"} $2=="No" {$2="?"} 1' file
      

      【讨论】:

      • 请注意,可以有超过 3 列。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-29
      • 1970-01-01
      • 1970-01-01
      • 2014-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多