如何在逗号分隔文件中使用 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
我正在处理 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