如何在逗号分隔文件中使用 bash 将 00 替换为 Na,不包括第一行和第一列

How to replace 00 with Na excluding first row & first column using bash in comma separated file

我正在处理 GWAS 数据,我的数据如下所示:

IID,kgp11004425,rs11274005,kgp183005,rs746410036,kgp7979600
1,00,AG,GT,AK,00
32,AG,GG,AA,00,AT
100,TT,AA,00,AG,AA       
3,GG,AG,00,GT,GG

期望的输出:

IID,kgp11004425,rs11274005,kgp183005,rs746410036,kgp7979600
1,N/A,AG,GT,AK,N/A
32,AG,GG,AA,N/A,AT
100,TT,AA,N/A,AG,AA       
3,GG,AG,N/A,GT,GG

我在这里尝试用“N/A”替换“00”,但由于我在第一行和第一列 (IID) 中有 00,所以我使用的命令是:

sed '1!s~00~N/A~g' allSNIPsFinaldata.csv 

上面的命令排除了第一行而不是第一列,因此我得到的 IID 值 100、200 和 300 为 1N/A、2N/A 和 3N/A.任何人都可以帮助“如何排除第一行和第一列并执行上述操作。请帮助

如果你只想替换其他列中的 00,你必须在你的模式中添加一个分隔符(我假设在我的命令中使用 space): sed -i 's~ 00 ~ N/A ~g' allSNIPsFinaldata.csv

假设列由 space 个字符分隔,例如 whitespace 或制表符,请尝试:

sed -E '1!s~([[:space:]])00([[:space:]]|$)~N/A~g' allSNIPsFinaldata.csv
  • 地址 1! 跳过第一行。
  • 正则表达式 ([[:space:]])00([[:space:]]|$) 匹配 00 字符串 前面有一个 space 字符(它防止匹配第一个 列),然后是 space 字符或行尾。

一个awk:

$ awk '
BEGIN {
    FS=OFS=","          # set field delimiters to a comma
}
FNR>1 {                 # process records after the first
    for(i=1;i<=NF;i++)  # iterate all fields (maybe start from 2nd?)
        if($i=="00")    # if field is 00
            $i="N/A"    # replace
}1' file                # output

输出:

IID,kgp11004425,rs11274005,kgp183005,rs746410036,kgp7979600
1,N/A,AG,GT,AK,N/A
32,AG,GG,AA,N/A,AT
100,TT,AA,N/A,AG,AA       
3,GG,AG,N/A,GT,GG

在 GNU awk 中使用其 gensub 函数显示示例,请尝试以下 awk 程序。

awk '
BEGIN{
  FS=OFS=","
}
FNR==1{
  print
  next
}
{
  secondPart=gensub(/^[^,]*,(.*)/,"\1","g")
  sub(/^00,/,"N/A,",secondPart)
  gsub(/,00,/,",N/A,",secondPart)
  sub(/,00$/,",N/A",secondPart)
  print  OFS secondPart
}
'  Input_file

这可能适合您 (GNU sed):

sed -E '1!{s/,00(,|$)/,N\/A/g;s//,N\/A/g}' file

如果不是第一行且,后跟[=​​12=]后跟[=​​11=]或end-of-line,则将00替换为N/A其他部分保持不变

此替换是全局的,但需要执行两次,因为模式可能会重叠。

在每个 Unix 机器上的任何 shell 中使用任何 awk:

$ awk '{[=10=]=[=10=]","; gsub(/,00,/,",N/A,"); sub(/,$/,"")} 1' file
IID,kgp11004425,rs11274005,kgp183005,rs746410036,kgp7979600
1,N/A,AG,GT,AK,N/A
32,AG,GG,AA,N/A,AT
100,TT,AA,N/A,AG,AA
3,GG,AG,N/A,GT,GG

以上假定第一行的列名中的 none 将是确切的字符串 00。如果可以的话,只需将上面的内容调整为:

awk 'NR>1{[=11=]=[=11=]","; gsub(/,00,/,",N/A,"); sub(/,$/,"")} 1' file