Awk:带有数字数组的for循环

Awk: for-loop with array of numbers

如何使用 awk 在 for 循环中使用数字数组?

我试过了:

awk '{ for (i in [10, 12, 18]) print i }' myfile.txt

但是我遇到了语法错误

in 运算符适用于数组。从像 10 12 18 这样的数字列表创建数组的方法是 split() 包含这些数字的字符串。

将这些数字作为值存储在数组 a[] 中,索引为 13:

awk 'BEGIN{FS=OFS="|"; split("10 12 18",a," ")}
     (FNR>2)  { for(j in a) { i=a[j]; k=$i OFS $(i+1); c[k]++; d[k] = i } }
     END{for (k in c) print d[k],k,c[k] }' myfile.txt

将这些数字存储为数组 b[] 的索引,所有值都为 0-or-null(与未初始化的标量变量相同):

awk 'BEGIN{FS=OFS="|"; split("10 12 18",a," "); for (j in a) b[a[j]]}
     (FNR>2)  { for(i in b) { k=$i OFS $(i+1); c[k]++; d[k] = i } }
     END{for (k in c) print d[k],k,c[k] }' myfile.txt

如果您出于某种原因不想预先创建数组(例如,您要拆分的数字列表是动态创建的),那么您可以在每次需要时创建它,例如:

awk 'BEGIN{FS=OFS="|"}
     (FNR>2)  { split("10 12 18",a," "); for(j in a) { i=a[j]; k=$i OFS $(i+1); c[k]++; d[k] = i } }
     END{for (k in c) print d[k],k,c[k] }' myfile.txt

但显然多次创建同一个数组的效率低于创建一次。

kinda 对 for-loop 做了一个非常粗略的模拟,它直接接受一个列表,而不需要在此之前调用额外的函数来初始化它:

  • 它试图尽可能灵活地考虑 分隔符可能是,所以

    foreach("[CA=MX=JP=FR=SG=AUS=N.Z.]")
    

    实际上也可以。

  • 尽管下面显示了 gawk 配置文件, 并使用 PROCINFO 数组,您不需要 gawk 即可工作:

    • 它在 mawk 1.3.4mawk 1.9.9.6gnu gawk 5.1.1macos x
    • 上有效
  • 刚刚添加了一个 Unicode UTF8 功能,无论您的区域设置是什么,或者您使用的是 gawk mawk 还是 [=23],该功能都有效=]

    • 表情符号也很好用
  • 也就是说,它无法正确解析CSVXMLJSON输入 (没时间弄得那么花哨)

             list 1 ::  10
             list 1 ::  12
             list 1 ::  18.
             list 1 ::  27
             list 1 ::  36
             list 1 ::  pi
             list 1 ::  hubble
             list 1 ::  kelvins
             list 1 ::  euler
             list 1 ::  higgs
             list 1 ::  9.6
    
             list 2 ::  CA
             list 2 ::  MX
             list 2 ::  JP
             list 2 ::  FR
             list 2 ::  SG
             list 2 ::  AUS
             list 2 ::  N.Z.
    
     # gawk profile, created Mon May  9 22:06:03 2022
    
     # BEGIN rule(s)
    
     BEGIN {
     11      while (i = foreach("[10, 12, 18., 27, 36, pi, hubble, kelvins, euler, higgs, 9.6]")) {
     11          print "list 1 :: ", i
         }
      1      printf ("\n\n\n")
      7      while (i = foreach("[CA, MX, JP, FR, SG, AUS, N.Z., ]")) {
      7          print "list 2 :: ", i
         }
     }
    
    
     # Functions, listed alphabetically
    
     20  function foreach(_, __)
         {
     20      if (_=="") {
             return \
                  PROCINFO["foreach", "_"] = \
                  PROCINFO["foreach", "#"] = _
             }
     20      __ = "264"
    
     20      if (_!= PROCINFO["foreach", "_"]) { # 2
      2      
                 PROCINFO["foreach","_"]=_
    
      2          gsub("^[ \t]*[[<{(][ \t]*"\
                      "|[ \t]*[]>})][ \t]*$"\
                      "|\300|\301","",_)
    
                 gsub("[^"(\
                             "32"~"[^32]"\
                           ? "\200-\277"\
                              "\302-\364"\
                           : ""       \
                           )"[:alnum:]"\
                                        \   
                             "20""""-77" \
                          "000-577"  \
                           "600-777"   \
                        "0000-4777"\
                                                   \
                                     ".@$&%+-]+",__,_)
    
                 gsub("^"(__)"|"\
                         (__)"$","", _)
    
      2          PROCINFO["foreach","#"]=_
             }
     20      if ((_=PROCINFO["foreach","#"])=="") { # 2
      2          return _
             }
     18      sub((__) ".*$", "", _)
             sub("^[^"(__)"]+("(__)")?","",PROCINFO["foreach","#"])
     18      return _
         }
    
             list 2 ::  CA
             list 2 ::  MX
             list 2 ::  JP
             list 2 ::  FR
             list 2 ::  SG
             list 2 ::  눷
             list 2 ::  
             list 2 ::  N.Z.
    
      while(i = foreach("[CA=MX=JP=FR=SG=307"\
                        "=0741=N.Z.]")) { 
    
          print "list 2 :: ", i
      }