也许标题不是一个好的描述,但实质上,这是我试图解决的问题:
我没有被迫使用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
答案 0 :(得分:2)
awk '{for(i=1;i<=NF;i++){ if($i~/NoData/){ $i=last[i]; } last[i]=$i } }1' file
如果您想保留原始格式,可以使用下面的内容,如果您有gawk
split
的第4个参数可能会被使用。
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
或者设置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(保留格式)
$ 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
示例 - 2(不保留源格式)
默认情况下,它会将单个空格作为输出分隔符,如果您设置OFS
,它将覆盖默认值。
$ 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