【问题标题】:Sed/Awk remove entire section between 2 markes after a pattern matchSed/Awk 在模式匹配后删除 2 个标记之间的整个部分
【发布时间】:2017-11-03 14:15:02
【问题描述】:

给定一个具有多个 if 条件的 TCL 脚本,格式如下:

if { $var1 == "string1" || $var2 == "string2" ... } {
   line1
   line2
   line3
   ...
} else {
   line10
   line11
}

我正在寻找条件中出现 string1 的每个 if 语句,删除 if 条件并只保留 else 分支中的行。在上面的示例中,预期结果将是:

line10
line11

【问题讨论】:

  • 每个 if 语句? - 你的代码只有一个这样的ifstmt
  • 在上面的例子中我只包含了一个,但是文件可以有多个 if 类似于 string1 用于条件检查的那个
  • 嵌套ifs 怎么样?并嵌套了ifs 条件为string1
  • 假设没有嵌套的 if s 并且不会有任何嵌套。所有条件句都与上面的非常相似。
  • linex 看起来像什么?复杂的命令,或者?

标签: awk sed


【解决方案1】:

为此,您最好使用真正的 TCL 解析器,但这里有一个 awk 脚本(基本上是一个简单的状态机)来处理您提出的简单案例:

awk '/if.*string1/ {inif=1;next}
     inif && /\}\s*else\s*\{/ {inif=0;inelse=1;next}
     inif && /\}/ {inif=0;next}
     inelse && /\}/ {inelse=0;next}
     inelse {sub(/\s*/,"")}
     !inif' file

示例输入(问题的扩展示例):

$ cat file
if { $var1 == "string1" || $var2 == "string2" ... } {
   line1
   line2
   line3
   ...
} else {
   line10
   line11
}

if { $var1 == "string1" || $var2 == "string2" ... } {
   line1
   line2=2
   line3="2";
   ...
} else {
   line11
   line12
}

if { $var1 == "string1" || $var2 == "string2" ... } {
   # matching if block without else is also removed
}

if { something else } {
    test
}

结果:

$ awk '/if.*string1/ {inif=1;next}  inif && /\}\s*else\s*\{/ {inif=0;inelse=1;next}  inelse && /\}/ {inelse=0;next}  inelse {sub(/\s*/,"")}  !inif' file
line10
line11

line11
line12


if { something else } {
    test
}

【讨论】:

  • 我无法完成这项工作。我正在使用您的文件作为测试并在 tcsh 上(主要是我需要在 cshell 中工作)我得到:Unmatched '. 然后如果我在 #!/bin/sh 中创建一个脚本,我得到:awk: warning: escape sequence \}'视为普通}' awk: warning: escape sequence \s' 视为普通s' awk: warning: escape sequence \{' 视为普通{'
  • 当我使用 -F 选项运行时,我在 bash shell 中遇到了上述错误。如果我卸下开关,则根本没有输出。似乎什么也没做。
  • 不确定awk 3,但您可以尝试像脚本一样运行它,带有哈希爆炸#!/usr/bin/awk -f 和下一行中的程序/if.*string1/ {inif=1;next} inif && ...。另外,您可以尝试使用gawk,甚至可以安装最新版本的gawk..
  • 别担心,我已经整理好了。我对您的脚本进行了逆向工程并稍作修改,现在可以在两个版本上使用。还意识到在某些情况下,我想保留 if 分支而不是 else 部分,因此相应地进行了修改。现在一切都好。谢谢!
  • 感谢@MichaelShigorin,让我回到这个答案。检查时,我注意到一个案例处理不当(如果没有 else 则匹配),所以我修复了这个问题。谢谢!
最近更新 更多