繁体   English   中英

如何在Linux中替换多行模式

[英]how to replace pattern in multi-line in linux

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

/**
 * @something
**/

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

  1. “ grep”不起作用,因为这是多行模式。
  2. 我尝试使用“ sed”,但是无法正常工作。
  3. 我想“ awk”可能很容易,但是“ awk”似乎太复杂了,我对“ awk”并不熟悉。

假设我们的输入文件是:

$ 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=1设置c=1 c停留在一个位置,直到下一个注释行**/出现为止,在这种情况下, c设置回0。仅当c=0时才打印该行。 在打开和关闭注释行之间的任何内容,无论格式如何,都不会打印。

该代码看起来很有趣,因为/*都是awk活动字符。 因此,它们都需要避免反弹。 因此,例如,用于查找注释开始行的正则表达式看起来像\\/\\*\\*而用于注释结束的正则表达式看起来像\\*\\*\\/

更复杂的输入文件

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

$ cat file
something
/**
 * @something
**/ random
hello
hi /**
 * @something
**/ bye
hola
gracias
bye

我们可以使用awk如下处理:

$ awk -v RS='\\*\\*/\n*' '{sub(/\n*\/\*\*.*/,"",$0); print $0}' file
something
 random
hello
hi 
 bye
hola
gracias
bye

上面已经用GNU awk进行了测试。 由于它使用多字符记录分隔符,因此可能不适用于较早版本的awk

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

这是一个简单的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}'

将GNU awk用于多字符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
cat text.txt | egrep -v "[/]" | egrep -v "[*] @" > newtext.txt

可以做到这一点,但是您可能必须根据文件中的其他内容稍作修改。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM