Awk 将模式匹配字段替换为字段';s上一行的值

Awk 将模式匹配字段替换为字段';s上一行的值,awk,replace,pattern-matching,field,Awk,Replace,Pattern Matching,Field,也许标题不是一个很好的描述,但本质上,这就是我试图解决的问题: 我有一个文本文件,每行有n行和m个空格分隔符字段 如果第i行的字段j与模式匹配,则将其替换为第i-1行的字段j 我没有被迫使用AWK(在这个例子中是GAWK),但它似乎是这个操作的一个好选择。这是我编写的sript,它可以按预期工作,但我想知道是否有一种更省时的方法来解决这个问题 { if ($0!~/NoData/) { split($0, data, " "); print $0

也许标题不是一个很好的描述,但本质上,这就是我试图解决的问题:

  • 我有一个文本文件,每行有n行和m个空格分隔符字段
  • 如果第i行的字段j与模式匹配,则将其替换为第i-1行的字段j
我没有被迫使用AWK(在这个例子中是GAWK),但它似乎是这个操作的一个好选择。这是我编写的sript,它可以按预期工作,但我想知道是否有一种更省时的方法来解决这个问题

{
    if ($0!~/NoData/) {
        split($0, data, " ");
        print $0
    } else {
        split($0, row, " ", seps);
        for(i in row) {if (row[i]~/NoData/) row[i]=data[i]; else data[i]=row[i]; printf "%s%s", row[i], seps[i];}
        printf "\n"                                                                                                                                               
    }
}
作为示例,脚本运行在此输入文件上

0.8147    0.2785    0.9572    0.7922    0.6787    0.7060
0.9058    0.5469    0.4854    0.9595    0.7577    0.0318
0.1270    0.9575    0.8003    0.6557    0.7431    0.2769
0.9134    0.9649    NoData    0.0357    0.3922    0.0462
0.6324    0.1576    NoData    NoData    0.6555    0.0971
0.0975    0.9706    NoData    NoData    0.1712    0.8235
应该会产生这样的结果

0.8147    0.2785    0.9572    0.7922    0.6787    0.7060
0.9058    0.5469    0.4854    0.9595    0.7577    0.0318
0.1270    0.9575    0.8003    0.6557    0.7431    0.2769
0.9134    0.9649    0.8003    0.0357    0.3922    0.0462
0.6324    0.1576    0.8003    0.0357    0.6555    0.0971
0.0975    0.9706    0.8003    0.0357    0.1712    0.8235
或者通过设置OFS=“”或OFS=

awk -v OFS= '{
       split($0,D,/[^[:space:]]*/);
       for(i=1;i<=NF;i++){ 
            if($i~/NoData/){ $i =  last[i]; } 
            last[i]=$i ; 
            $i = sprintf("%s%s",D[i],$i) 
       }  
 }1' file

哇,又快又短。最后的1有什么作用?@Patrik
1
执行默认操作
print$0
(打印当前行/记录/行),这意味着它的真值可以是任何非零数字,谢谢。我认为保留格式不是优先事项,因为输出将被其他程序解析。只要至少有一个,就可以space@Patrik:好的,那么没问题,但是为了满足预期的o/p,我给出了其他解决方案。
awk '{
       split($0,D,/[^[:space:]]*/);
       s = "";
       for(i=1;i<=NF;i++){ 
            if($i~/NoData/){ $i =  last[i]; } 
            last[i]=$i ; 
            s = s  sprintf("%s%s",D[i],$i) 
       }  
       print s
 }' file
awk -v OFS= '{
       split($0,D,/[^[:space:]]*/);
       for(i=1;i<=NF;i++){ 
            if($i~/NoData/){ $i =  last[i]; } 
            last[i]=$i ; 
            $i = sprintf("%s%s",D[i],$i) 
       }  
 }1' file
$ cat file
0.8147    0.2785    0.9572    0.7922    0.6787    0.7060
0.9058    0.5469    0.4854    0.9595    0.7577    0.0318
0.1270    0.9575    0.8003    0.6557    0.7431    0.2769
0.9134    0.9649    NoData    0.0357    0.3922    0.0462
0.6324    0.1576    NoData    NoData    0.6555    0.0971
0.0975    0.9706    NoData    NoData    0.1712    0.8235

$ awk '{
       split($0,D,/[^[:space:]]*/);
       s = "";
       for(i=1;i<=NF;i++){ 
            if($i~/NoData/){ $i =  last[i]; } 
            last[i]=$i ; 
            s = s  sprintf("%s%s",D[i],$i) 
       }  
       print s
 }' file
0.8147    0.2785    0.9572    0.7922    0.6787    0.7060
0.9058    0.5469    0.4854    0.9595    0.7577    0.0318
0.1270    0.9575    0.8003    0.6557    0.7431    0.2769
0.9134    0.9649    0.8003    0.0357    0.3922    0.0462
0.6324    0.1576    0.8003    0.0357    0.6555    0.0971
0.0975    0.9706    0.8003    0.0357    0.1712    0.8235
$ cat file
0.8147    0.2785    0.9572    0.7922    0.6787    0.7060
0.9058    0.5469    0.4854    0.9595    0.7577    0.0318
0.1270    0.9575    0.8003    0.6557    0.7431    0.2769
0.9134    0.9649    NoData    0.0357    0.3922    0.0462
0.6324    0.1576    NoData    NoData    0.6555    0.0971
0.0975    0.9706    NoData    NoData    0.1712    0.8235

$ awk '{for(i=1;i<=NF;i++){ if($i~/NoData/){ $i=last[i]; } last[i]=$i }  }1' file
0.8147    0.2785    0.9572    0.7922    0.6787    0.7060
0.9058    0.5469    0.4854    0.9595    0.7577    0.0318
0.1270    0.9575    0.8003    0.6557    0.7431    0.2769
0.9134 0.9649 0.8003 0.0357 0.3922 0.0462
0.6324 0.1576 0.8003 0.0357 0.6555 0.0971
0.0975 0.9706 0.8003 0.0357 0.1712 0.8235