使用 sed/awk 过滤 YAML 文件内容

使用 sed/awk 过滤 YAML 文件内容

我有一个文本文件,其中包含以下内容。

$ cat hosts.yml
[prod_env]
foo.example.com
bar.example.com
[stage_env]
foo_stage.example.com
bar_stage.example.com
[dev_env]
foo_dev1.example.com
dev2_bar.example.com

我想过滤 bash 中 [prod_env] 文件下列出的主机。我以有限的知识尝试过 sed、awk 和 grep,但我不知道如何过滤它们。

示例:我想打印 prod_env 和 dev_env 下的主机。所以最终的输出将是:

foo.example.com 
bar.example.com 
foo_dev1.example.com 
dev2_bar.example.com

答案1

解决方案sed

sed -nEe '/\[(prod|dev)_env]/!d;N;:loop' -e 's/.*\n//;${p;d;};N;P;/\n\[/D;bloop' hosts.yml
  • /\[(prod|dev)_env]/!d删除所有行,直到找到[prod_env][dev_env]找到
  • N;:loop添加下一行并开始循环
  • 在循环内部,我们删除两行中的第一行s/.*\n//,因为它要么是该[...env]行,要么我们已经在最后一个循环周期中打印了它
  • ${p;d;}如果我们在打印时到达最后一行,则打印剩余的行
  • N;P添加下一行并打印当前行
  • /\n\[/D查看下一行是否以 开头[。在这种情况下,缓冲区中的第一行(已打印)可以被丢弃,我们从该[行开始
  • bloop否则循环

您可以逐行进行操作,而不是将下一行添加到缓冲区,打印并删除旧行,但这将需要另一个循环,因为您无法重新开始D

答案2

你可以(在 Mac 上):

tr "\n" "\t" < hosts.yml | sed $'s%\t\\[%\\\n\[%g' | grep 'prod\|dev' | sed $'s%.*\]\\\t%%g' | tr "\t" "\n"
  1. tr将把一切都放在一条线上
  2. 第一个sed将在每个部分之前换行
  3. grep会剪出你想要的线条(部分)
  4. 其次sed将删除 [] 部分。
  5. 最后tr将换行,以便每行获得一个主机名。

答案3

awk 'BEGIN{RS="[";FS="]\n"} 
     $1 ~/(prod|dev)_env/ {print $2}' ex1

答案4

您可以使用GNU sed如下所示的方法来执行此操作:

$ sed -nEe '
   /\[/!{H;$!d;}
   x;1!s/^\[(prod|dev)_env]\n//p
' hosts.yml

相关内容