我有一个读取的数据文件
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 $
我不想在最后一个和$
之间留出空格答案 0 :(得分:3)
像这样,例如:
$ awk 'BEGIN{OFS=FS="\t"} {for (i=1; i<NF; i++) if ($i=="No") $i="?"}1' a
? Yes No
Yes Yes Yes
? ? No
它从第1个字段到倒数第二个字段进行检查,并在必要时进行替换。
BEGIN{OFS=FS="\t"}
用于将输入和输出字段分隔符设置为选项卡。
答案 1 :(得分:3)
除非你有一些其他标题可以冒险匹配No
,否则你应该放弃一些非常简单的东西,例如:
perl -pwe 's/\bNo\b(?!\s*$)/?/g' infile > outfile
将替换围绕它们的字边界的所有No
字符串。 Shell重定向将输出存储在新文件中。您也可以使用-i
开关,但我通常不建议新用户使用。
使用否定前瞻断言确保它不是该行的最后一个匹配。
答案 2 :(得分:2)
使用awk:
awk -v ccol=3 '{for (i=1; i<=NF; i++) if (i != ccol && $i=="No") $i="?"} 1' OFS='\t' file
您可以传递ccol
的任何值,以跳过要替换的列。
答案 3 :(得分:1)
这里我认为不能替换最后一列(必要时可以很容易地进行调整)。
使用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
答案 4 :(得分:0)
另一个awk
awk '$1=="No" {$1="?"} $2=="No" {$2="?"} 1' file