带有 break 语句的 AWK for 循环
AWK for-loop with break statment
今天我正在解决一个问题,纠正文件中有一些未知数的数据错误。未知数是每个文件中的字段数,以及哪些字段和记录具有字符串“---”。
数据示例为:
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 [=12=]}}' 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 [=14=]}}' 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 语句,但经过数小时的搜索,我找不到对我有帮助的示例。我知道给猫剥皮的方法不止一种,所以如果您知道实现我的目标的更好方法,请记住有多个文件具有不同的字段数,或者您可以提供一个中断语句的示例我和其他正在寻找示例的 for 循环之一将不胜感激。
谢谢
这应该有效
$ 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 --- --- --- --- --- --- --- ---
您只需要一个简单的替换,这就是 sed 的理想工作:
$ sed -E 's/(-+ +)[^ ]+/ /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 --- --- --- --- --- --- --- ---
今天我正在解决一个问题,纠正文件中有一些未知数的数据错误。未知数是每个文件中的字段数,以及哪些字段和记录具有字符串“---”。
数据示例为:
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 [=12=]}}' 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 [=14=]}}' 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 语句,但经过数小时的搜索,我找不到对我有帮助的示例。我知道给猫剥皮的方法不止一种,所以如果您知道实现我的目标的更好方法,请记住有多个文件具有不同的字段数,或者您可以提供一个中断语句的示例我和其他正在寻找示例的 for 循环之一将不胜感激。
谢谢
这应该有效
$ 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 --- --- --- --- --- --- --- ---
您只需要一个简单的替换,这就是 sed 的理想工作:
$ sed -E 's/(-+ +)[^ ]+/ /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 --- --- --- --- --- --- --- ---