【问题标题】:Bash sed command to delete all lines matched within a parameter for in AndroidBash sed命令删除Android中参数中匹配的所有行
【发布时间】:2016-07-06 06:43:47
【问题描述】:

我坚持使用 sed 命令删除文件中的所有匹配项和匹配项的参数。我尝试了许多不同的组合,但我无法完全得到满足我需要的命令。

这是我的 sed 命令:

sed -i '/test {/,/}/d' $FILE

这是我要删除的比赛:

  test {
    library proxy
    uuid 9d4921da-8225-4f29-aefa-6e6f69726861

    libsw {
      library test_sw
      uuid 6ab06da4-c516-4611-8166-6168726e6f69
    }

    libhw {
      library test_hw
      uuid a0c30891-8246-4aef-b8ad-696f6e726861
    }
  }

不幸的是,我的命令导致上面的行没有被删除:

     libhw {
      library test_hw
      uuid a0c30891-8246-4aef-b8ad-696f6e726861
    }
  }

我的命令有效并删除了以下的整个匹配/参数:

  test {
    library test
    uuid f1c02420-777f-11e3-981f-0800200c9a66
  }

我将非常感谢能够了解我做错了什么,并可能修复以帮助我解决此问题。

【问题讨论】:

  • 请显示预期的输入和输出。也不要使用-i 来测试代码。

标签: android linux bash sed parameters


【解决方案1】:

使用 GNU sed

sed -z 's/test {[^{}]*\({[^}]*}[^{}]*\)*}//g' testfile

-z 告诉 sed 读取文件中的所有字符,直到第一个 NUL 字符。由于没有任何合理的源/文本文件具有 NUL 字符,因此这与读取整个文件相同。

替换命令删除您要删除的文本。更详细:

  • test {[^{}]* 匹配 test { 字符串,后跟任意数量的非花括号字符。

  • \({[^}]*}[^{}]*\)* 匹配任意数量的组 \(...\),包含一个左大括号 {,任意数量的非大括号 [^}]*,后跟一个右大括号, },后跟任意数量的非花括号 [^{}]*

  • } 匹配与test { 中的左大括号相对应的右花括号。

使用其他sed

如果我们使用的 sed 不支持 -z 标志,那么我们需要添加命令以一次读取多行。例如:

sed  'H;1h;$!d;x; s/test {[^{}]*\({[^}]*}[^{}]*\)*}//g' testfile

同时删除包含最后一个 }

的行

此变体将 (a) 删除 text { 之前的所有空格,并且 (b) 删除结束 } 之后的行上的所有空格以及它后面的换行符:

sed  'H;1h;$!d;x; s/[[:blank:]]*test {[^{}]*\({[^}]*}[^{}]*\)*}[[:blank:]]*\n//g' file

使用 awk

awk '/test {/{f=1; n=0} !f{print} {n+=gsub(/{/,"{", $0)-gsub(/}/,"}",$0)} n==0{f=0}' testfile

这里,变量f 跟踪我们何时处于test 块中。变量n 跟踪有多少打开的{。一旦我们进入test 块,这将停止打印,直到最后打开的{ 关闭。

  • /test {/ {f=1; n=0}

    当我们到达包含字符test { 的行时,我们将f 设置为1,将n 设置为零。

  • !f{print}

    如果f 为零,我们打印该行。

  • n+=gsub(/{/,"{", $0) - gsub(/}/,"}",$0)

    这会更新打开{ 的计数。 gsub(/{/,"{", $0) 返回 { 的数量,而 gsub(/}/,"}",$0) 返回 } 的数量。我们将这两个数字相减,得到开括号中的净变化。

  • n==0 {f=0}

    当左大括号计数降至零时,我们将f 设置为零以指示test { 组的完成。

【讨论】:

  • 其他 sed 部分工作。首先,这是一个脚本,外部脚本文件不在 $test 文件内,因此 sed 命令在脚本文件内输出,而不是更改 $test 文件本身。该命令还保留最后一个 } 之前的空格,而不是删除整行。
  • @AhrionGallegos 如果要就地更改文件,可以将-i 选项与sed 结合使用。要使用 awk 就地更改文件,假设您有一个现代 GNU awk,然后添加选项 -i inplace。如果这不是您要问的,请澄清。
  • 很遗憾,我无法执行 awk。但是,我正在尝试从单独文件中的命令行更改现有文件,这就是我们所说的命令。所以我正在执行命令来修补外部文件。所以这会到位吗? sed -i 'H;1h;$!d;x; s/test {[^{}]*({[^}]*}[^{}]*)*}//g' $VENDOR_CONFIG 出现“sed no temp file”错误
  • “我正在尝试在单独的文件中从命令行更改现有文件” 使用 sed -i .... 应该可以正常工作。我刚刚在 Android 上测试了 sed -i 'H;1h;$!d;x; s/test {[^{}]*\({[^}]*}[^{}]*\)*}//g' testfile,它的工作正常。
  • 天哪,我没有挂载我的存储。它确实奏效了。它没有删除包含“}”的最后一行,而是删除了 },但留下了“”空格和该行。如何删除包含最后一个 } 的行以及空格?顺便说一句,你是救生员。从来没有意识到这些 sed 命令在与 awk 或通用 Java 代码的 co.parison 中是多么令人困惑。
【解决方案2】:

试试这个:

awk  '/test {/{a=1} /{/ {f++} f==0&&a==1{a=0} /}/{f--} a==0{print}' file

【讨论】:

    猜你喜欢
    • 2020-05-07
    • 1970-01-01
    • 2012-08-01
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多