【问题标题】:Delete lines between two patterns in shell删除shell中两个模式之间的行
【发布时间】:2018-02-13 10:34:42
【问题描述】:

我需要删除 ,( 之间的多行,包括模式以及第一次出现时的行。

示例

Test ,

 this 

is the 
deletion 
part 
(
done...

预期输出

Test 
done

我尝试了以下使用 sed 来实现上述输出,但它只返回整个文件数据。

sed 's/,*(//' file

提前致谢。

【问题讨论】:

  • 请解释您的代码(您希望它的工作方式,而不是它的工作方式),它似乎与您描述的目标非常无关,这使得问题模棱两可和不清楚。跨度>
  • @Yunnosch 我提供了一个示例,说明我打算如何使代码工作:)

标签: bash shell perl awk sed


【解决方案1】:
awk '{sub(/ ,|\.../,"")}NR==1;END{print}' file

Test
done

【讨论】:

  • 这不符合 OP 的要求 - 它应该从 "," 删除,直到 "("。(对它的工作原理做一点解释也很好!)
【解决方案2】:

awk 更适合这里:

awk '/,/{p=1; sub(/[ \t]*,.*/, ""); print} !p; /\(/{p=0}' file

Test
done

或者你也可以使用perl:

perl -i -0777 -pe 's/\h*,.*\(//s' file

或者这个带有不需要s修饰符的否定字符类的正则表达式:

perl -i -0777 -pe 's/\h*,[^(]*\(//' file

【讨论】:

  • [\s\S]不错:-)
  • 其他选项是使用s 修饰符,如's~,(?s).*\(~~'
  • perl 更经常使用正则表达式之外的修饰符 s/...//s
  • @anubhava 非常感谢。
  • 可能想要[^(]* 而不是.*(停在第一个()。
【解决方案3】:

这可能对你有用(GNU sed):

sed -z 's/,[^(]*(//g' file

将整个文件放入内存并全局替换 ,( 之间的任何字符。

【讨论】:

    【解决方案4】:

    使用 sed:

    sed '/Test/,/done/{//!d;s/ ,$//}' file
    

    /Test/,/done/:从匹配Test的行到匹配done的下一行:

    • //!d 删除除与地址匹配的行之外的所有行(Test ,done
    • s/ ,$// 从地址中删除第一次出现的,

    【讨论】:

    • @bfontaine 我添加了一些解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-02
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-12
    相关资源
    最近更新 更多