【问题标题】:AWK for-loop with break statment带有 break 语句的 AWK for 循环
【发布时间】:2017-03-31 06:59:40
【问题描述】:

今天,我正在解决一个问题,纠正具有一些未知数的文件中的数据错误。未知数是每个文件中的字段数,以及哪些字段和记录具有字符串“---”。

数据的一个例子是:

1  2  1    39.6406  1    38.8512  1    38.3479  1    37.9744
2  1  4    39.1527  3    38.7329  2    38.3479  2    37.9744
3  3  3    39.5186  2    38.8512  3    38.2079  3    37.6385
4  4  2    39.6406  4    38.4964  ---  37.7414  ---  36.7149
5  5  ---  40.2504  ---  39.0286  ---  38.4879  ---  38.1004

想要的输出是:

1  2  1    39.6406  1    38.8512  1    38.3479  1    37.9744
2  1  4    39.1527  3    38.7329  2    38.3479  2    37.9744
3  3  3    39.5186  2    38.8512  3    38.2079  3    37.6385
4  4  2    39.6406  4    38.4964  ---  ---      ---  ---
5  5  ---  ---      ---  ---      ---  ---      ---  ---

我尝试过使用for循环,例如:

awk '{for (i = NF; i >= 1; i--){if ($i=="---")$(i-1)="---"}{print $0}}' file 

导致:

1    2  1  39.6406  1  38.8512  1  38.3479  1  37.9744
2    1  4  39.1527  3  38.7329  2  38.3479  2  37.9744
3    3  3  39.5186  2  38.8512  3  38.2079  3  37.6385
---
---

我也试过了:

awk '{for (i=1;i<=NF;i++){if ($i=="---")$(i+1)="---"}{print $0}}' file

导致错误:

"awk: program limit exceeded: maximum number of fields size=32767"
    FILENAME="file" FNR=4 NR=4
1  2  1  39.6406  1  38.8512  1  38.3479  1  37.9744
2  1  4  39.1527  3  38.7329  2  38.3479  2  37.9744
3  3  3  39.5186  2  38.8512  3  38.2079  3  37.6385

在我的第一次尝试中,for循环一直到第一个字段,而在第二次尝试中,具有所需字符串的记录出现了无限循环。

我的直觉是我需要应用一个 break 语句,但经过数小时的搜索,我找不到对我有帮助的示例。我知道给猫剥皮的方法不止一种,所以如果你知道一种更好的方法来实现我的目标,请记住有多个文件具有不同的字段计数,或者如果你可以提供一个 break 语句的示例我的一个 for 循环、我和其他正在寻找示例的人将非常感激。

谢谢

【问题讨论】:

  • 我看到的一个问题是您没有在每次迭代中将索引增加/减少两个并且重叠范围。

标签: if-statement for-loop awk break


【解决方案1】:

这应该可以工作

$ awk '{for(i=3;i<NF;i+=2) if($i=="---") $(i+1)=$i}1' file | 
  column -t

1  2  1    39.6406  1    38.8512  1    38.3479  1    37.9744
2  1  4    39.1527  3    38.7329  2    38.3479  2    37.9744
3  3  3    39.5186  2    38.8512  3    38.2079  3    37.6385
4  4  2    39.6406  4    38.4964  ---  ---      ---  ---
5  5  ---  ---      ---  ---      ---  ---      ---  ---

【讨论】:

  • 谢谢,我要把它加到我的魔法书里:-)
【解决方案2】:

您所需要的只是一个简单的替换,因此这是 sed 的理想工作:

$ sed -E 's/(-+ +)[^ ]+/\1\1  /g' file
1  2  1    39.6406  1    38.8512  1    38.3479  1    37.9744
2  1  4    39.1527  3    38.7329  2    38.3479  2    37.9744
3  3  3    39.5186  2    38.8512  3    38.2079  3    37.6385
4  4  2    39.6406  4    38.4964  ---  ---      ---  ---
5  5  ---  ---      ---  ---      ---  ---      ---  ---

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-19
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多