【问题标题】:Ubuntu bash awk odd behaviourUbuntu bash awk 奇怪的行为
【发布时间】:2016-05-16 17:19:14
【问题描述】:

我正在尝试使用以下命令从 yml 文件中删除一个块,

awk '$1 == "tool:"{t=1}
   t==1 && $1 == "ports:"{t++; next}
   t==2 && /:[[:blank:]]*$/{t=0}
   t != 2' file.yml

对于下面的yml,

tool:
  image: tool.xxx.com/platform/app:dev
  log_driver: syslog
  restart: always
  ports:
    - "54325:80"
    - "543325:80"
  volume:
    - "a:b"

tool1:
  image: tool1.xxx.com/platform/app:dev
  log_driver: syslog
  restart: always
  ports:
    - "54325:80"
    - "543325:80"
  volume:
    - "a:b"

目标是从tool 主块中删除ports 子块。 来自https://stackoverflow.com/a/37256824/698072 的这个答案在尝试here 时似乎完全有效。但它正在从端口中删除所有内容,直到我的 Ubuntu 14.04 中的 yml 文件结束(在 14.04 的多个系统中的 sh 和 zsh 中都尝试过)。

预期:

tool:                                                                                                                                                                                                                     
  image: tool.xxx.com/platform/app:dev                                                                                                                                                                                    
  log_driver: syslog                                                                                                                                                                                                      
  restart: always                                                                                                                                                                                                         
  volume:                                                                                                                                                                                                                 
    - "a:b"                                                                                                                                                                                                               

tool1:                                                                                                                                                                                                                    
  image: tool1.xxx.com/platform/app:dev                                                                                                                                                                                   
  log_driver: syslog                                                                                                                                                                                                      
  restart: always                                                                                                                                                                                                         
  ports:                                                                                                                                                                                                                  
    - "54325:80"                                                                                                                                                                                                          
    - "543325:80"                                                                                                                                                                                                         
  volume:                                                                                                                                                                                                                 
    - "a:b" 

输出:

tool:
  image: tool.xxx.com/platform/app:dev
  log_driver: syslog
  restart: always

对这个特殊案例的任何帮助都会非常棒。

【问题讨论】:

  • 请不要包含控制台会话的图像。将文本复制并粘贴到您的问题中。
  • 您使用的是什么版本的 awk?并非所有都支持字符类 ([[:blank:]]),因此请尝试使用 [ \t]

标签: linux bash ubuntu awk


【解决方案1】:

我在之前的 awk 命令中做了一些更改,以防止您的 yml 有 DOS 行结尾。

awk '{sub(/\r$/, "")}
     $1 == "tool:"{t=1}
     t==1 && $1 == "ports:"{t++; next}
     t==2 && /:\s*$/{t=0}
     t != 2' file.yml

看起来 Ubuntu awk 不支持 POSIX 类 [[:blank:]][[:space:]],所以我们需要使用 \s 来匹配空格。

【讨论】:

  • 这完全有效,echo "$(cat docker-compose.yml)" | awk '$1 == "tool:"{t=1} t==1 && $1 == "ports:"{t++; next} t==2 && /s*$/{t=0} t != 2'。感谢您宝贵的时间,很抱歉给您带来了困惑..
  • 您的 Ubuntu 上安装了哪个版本的 awk? gawk 绝对支持 posix 类。
  • 是的 gnu awk 甚至 BSD awk 绝对支持 POSIX 类。看来我的 Ubuntu 附带了mawk 1.3.3
  • 支持简写\s但不支持简写[:space:]真是太棒了!
【解决方案2】:

如果文件是在 windows 上创建的,因此具有 windows 行结尾 (CR-LF),则模式 /:[[:blank:]]*$/ 将失败

[[:blank:]] 只匹配制表符和空格。要匹配任何空白字符,包括\r(回车),请使用[[:space:]]

如果这确实是问题所在,请考虑使用dos2unix 或类似方法来删除不正确的行尾,因为它们会导致其他实用程序出现其他问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-23
    • 2014-07-29
    • 2017-08-06
    • 1970-01-01
    • 1970-01-01
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多