【问题标题】:awk getline without advancing the fileawk getline 不推进文件
【发布时间】:2020-11-12 02:25:52
【问题描述】:

我有一个包含以下部分的文件:

requests:
  cpu: X
  memory: 500Mi
limits:
  cpu: Y
  memory: 1Gi

当我找到requests:\n cpu: X 时,我想将其与limits:\n cpu: Y 进行比较。根据 Y 的值,我想编辑 X。所以当我到达 cpu: X 时,我想向前扫描几行以查看 cpu: Y 的值是什么,然后返回到文件中的原始位置这样我就可以打印cpu: X_2(其中X_2是修改后的值)和剩余的行。

如果我使用getline,文件中的位置将被提前。当我使用 getline 读取并打印整个缓冲区时,我可以将所有内容保存到缓冲区中,但我希望有一种方法可以使用 getline 而不推进文件中的位置,或者重置位置。

示例代码:

awk '
        /requests:/ {
                print $0
                
                # search next 2 lines for cpu
                for (i=1; i<=2; i++) {
                        getline
                        ### Something to check the value of limits' cpu needs to go here
                        if ($0 ~ /cpu:/) {
                                print gensub(/cpu: .*/, "cpu: X_2", "g", $0)
                        }
                        else {
                                print $0
                                break
                        }
                }
                next
        }
        
        { print $0 }
'

添加预期输出:

例如,假设我希望请求的 cpu 不超过限制 cpu 的一半。该文件是一个有效的 yaml 文件,文件中的所有其他内容都需要保持不变。下面的 A、B、C 等用于说明不应修改的可能文件内容。

输入:

A: 1
B: 2
  b1: 1b
  b2: 2b
C: 3
  requests:
    cpu: 200m
    memory: 500Mi
  limits:
    cpu: 300m
    memory: 1Gi
D: 
  - d1a: 1da
    d1b: 1db
  - d2a: 2da
    d2b: 2db
E: 5
  requests:
    cpu: 100m
    memory: 500Mi
  limits:
    cpu: 500m
    memory: 1Gi
F:
  f1: 1f
  f2: 2f

输出:

A: 1
B: 2
  b1: 1b
  b2: 2b
C: 3
  requests:
    cpu: 150m
    memory: 500Mi
  limits:
    cpu: 300m
    memory: 1Gi
D: 
  - d1a: 1da
    d1b: 1db
  - d2a: 2da
    d2b: 2db
E: 5
  requests:
    cpu: 100m
    memory: 500Mi
  limits:
    cpu: 500m
    memory: 1Gi
F:
  f1: 1f
  f2: 2f

在这种情况下,cpu: 200m 的第一个实例被缩减为 cpu: 150m since 200 大于 300 的一半。第二个实例为 100m 的 cpu 没有被修改,因为它已经小于 500m 的一半。

【问题讨论】:

  • 您最好使用yq
  • 使用 getline 很少是正确的方法(请参阅 awk.freeshell.org/AllAboutGetline),它也不是解决您的问题的正确方法。请edit您的问题显示确切的预期输出,以便我们为您提供帮助。
  • 我不反对与 awk 不同的工具。我以前没用过yq。
  • @RustyLemur,能否请您告诉我们是否可以在您的系统中安装 yq,如果不能,我们可以提供其他工具(通常专家不推荐,因为 yq 是专门针对专为此类任务而设计)。
  • 是的,yq 是我使用的候选对象。

标签: awk getline


【解决方案1】:

双重处理文件并缓存 cpu 值以在第二轮中引用更容易。

$ awk 'function min(x,y) {return x<y?x:y} 
       FNR==1{c=0} 
       NR==FNR && /cpu:/ {sub("m","",$2); cpu[++c]=$2; next} 
       /cpu:/            {c++; 
                          if(c%2) 
                            {t=$2; 
                             sub("m","",t); 
                             v=int(min(cpu[c+1]/2,t)); 
                             sub($2,v"m")}}1' file{,}

【讨论】:

    猜你喜欢
    • 2012-08-07
    • 1970-01-01
    • 2015-05-06
    • 2019-02-20
    • 1970-01-01
    • 2015-01-05
    • 2014-08-12
    • 2013-02-28
    • 2014-07-29
    相关资源
    最近更新 更多