将连续制表符替换为“\tNA\t”

substitute consecutive tabs for "\tNA\t"

有一个格式错误的 tsv 文件,到处都是空白字段。我希望在 linux.

上用 "NA" 填充这些空的 space

我试过 awk '{gsub("\t\t","\tNA\t"); print[=11=])' 但那只会用一个空的 space 代替 NA 实例。链接命令 awk '{gsub("\t\t","\tNA\t"); print[=12=])|awk '{gsub("\t\t","\tNA\t"); print[=12=]) 每行执行两次替换 - 但如果我有很多列要处理,则不是特别有用。

有没有更快(更简洁)的方法来做到这一点?

你试过sed了吗?例如:

cat test.txt
test        test        test
test        test        test

sed 's:\t\t*:\tNA\t:g' test.txt

test    NA  test    NA  test
test    NA  test    NA  test

好的,这有效: awk '{ gsub(/\t\t\t/,"\tNA\tNA\t"); print [=10=]}' test.txt | awk '{ gsub(/\t\t/,"\tNA\t"); print [=10=]}' | awk '{ gsub(/\t\t/,"\tNA\t"); print [=10=]}' | awk '{gsub(/^[\t]+/,"NA\t"); print [=10=]}'

有趣的是,这不是: awk '{ gsub(/\t\t\t/,"\tNA\tNA\t"); print [=11=]}' test.txt | awk '{ gsub(/\t\t/,"\tNA\t"); print [=11=]}' | awk '{gsub(/^[\t]+/,"NA\t"); print [=11=]}'

不过我相信还有更优雅的解决方案..

它有点复杂,因为您必须处理换行空字段、行尾空字段和可能连续的空字段。我无法用 sed 实现某些目标,这可能是疯了。但是对于 awk 这似乎有效:

$ cat test.txt
a       c   d   e
    g   h   i   j
k   l   m   n   
p           s   t
        w   x   

$ awk -F$'\t' '{for(i=1;i<=NF;++i){if($i==""){printf "NA"}else{printf $i} if(i<NF)printf "\t"} printf "\n"}' test.txt 
a   NA  c   d   e
NA  g   h   i   j
k   l   m   n   NA
p   NA  NA  s   t
NA  NA  w   x   NA

当心复制粘贴,制表符可能会被转换成空格...顺便说一下,我搜索了 CSV 文件的解决方案,并从 this thread 改编了它;) 在那里你可以看到最多可读选项是 awk 选项。