如何在linux中多行替换模式

时间:2014-04-10 20:56:35

标签: regex linux command-line sed awk

假设我有一个名为text.txt的文件 在text.txt中,我有以下几种模式:

/**
 * @something
**/

我想将此模式替换为空字符串。执行此操作的最简单的Linux命令是什么?

  1. " grep的"不起作用,因为这是多线模式。
  2. 我试过" sed"但我无法让它运作起来。
  3. 我想" awk"可能很容易,但是" awk"看起来很复杂,我不熟悉" awk"。

4 个答案:

答案 0 :(得分:0)

假设我们的输入文件是:

$ cat text.txt
before
/**
 * @something
**/
after

我们可以使用awk过滤掉评论:

$ awk '/\/\*\*/ {c=1; next} /\*\*\// {c=0; next} c==0 {print}' text.txt
before
after

awk通过将变量作为标记c来工作。当我们开始时,c=0表示我们没有发表评论。当评论开始行/**出现时,我们会设置c=1c保持为1,直到下一个评论结束行**/出现,在这种情况下,c会重新设置为0.只有{{1}才打印出该行}。打印和关闭注释行之间的任何格式都不会打印出来。

代码看起来很滑稽,因为c=0/都是*的有效字符。因此,它们都需要使用反斜杠进行转义。因此,例如,用于查找注释开始行的正则表达式看起来像awk,而用于注释结束的正则表达式看起来像\/\*\*

更复杂的输入文件

假设输入文件具有更复杂的结构,如JS的示例所示:

\*\*\/

我们可以使用$ cat file something /** * @something **/ random hello hi /** * @something **/ bye hola gracias bye 处理此问题,如下所示:

awk

以上用GNU $ awk -v RS='\\*\\*/\n*' '{sub(/\n*\/\*\*.*/,"",$0); print $0}' file something random hello hi bye hola gracias bye 测试。由于它使用多字符记录分隔符,因此可能无法使用旧版本的awk

虽然awk通常逐行读取文件,但在上面的版本中,我们设置了记录分隔符awk,以匹配评论的结尾。然后,我们删除从注释开始到记录结尾的所有内容并打印记录。

答案 1 :(得分:0)

这是一个简单的awk,用于将文本从给定模式中移除:

cat file
before
/**
 * @something
**/
after

awk '/\*\*\//{f=0} f; /\/\*\*/{f=1}' file
 * @something

当您不想包含START / END模式时,这是处理此问题的最简单awk之一:

awk '/END/{f=0} f; /START/{f=1}'

答案 2 :(得分:0)

使用GNU awk for multi-char RS将整个文件作为一个字符串读取:

如果你只想删除你发布的字符串,那就是:

$ cat file
foo/**
 * @something
**/bar and more/**
 * @something
**/stuff

$ awk -v RS='^$' -v ORS= -v pat='/**
 * @something
**/' '{
    while ( s=index($0,pat) ) {
        $0 = substr($0,1,s-1) substr($0,s+length(pat))
    }
    print
}' file
foobar and morestuff

或者如果您实际上只想删除每次出现/**/之间的所有内容,则只需:

awk -v RS='/[*][*][^/]+/' -v ORS= '1' file
foobar and morestuff

答案 3 :(得分:-1)

cat text.txt | egrep -v "[/]" | egrep -v "[*] @" > newtext.txt

会这样做,但您可能需要稍微修改,具体取决于文件中的其他内容。