Regex linux中多行模式的替换
假设我有一个名为text.txt的文件 在text.txt中,我有以下几种模式:Regex linux中多行模式的替换,regex,linux,command-line,sed,awk,Regex,Linux,Command Line,Sed,Awk,假设我有一个名为text.txt的文件 在text.txt中,我有以下几种模式: /** * @something **/ 我想将此模式替换为空字符串。最简单的Linux命令是什么 “grep”不起作用,因为这是多行模式 我试过“sed”,但没能成功 我想“awk”可能很简单,但“awk”似乎很复杂,我对“awk”不太熟悉 假设我们的输入文件是: $ cat text.txt before /** * @something **/ after 我们可以使用awk过滤掉评论: $ awk
/**
* @something
**/
我想将此模式替换为空字符串。最简单的Linux命令是什么
假设我们的输入文件是:
$ 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
被设置回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
以上是用GNUawk
测试的。由于它使用多字符记录分隔符,因此可能无法与较旧版本的awk
一起使用
虽然awk
通常逐行读取文件,但在上面的版本中,我们设置了记录分隔符RS
,以匹配注释的结尾。然后,我们删除从注释开始到记录结束的所有内容,并打印记录
cat text.txt | egrep -v "[/]" | egrep -v "[*] @" > newtext.txt
可以,但您可能需要根据文件中的其他内容进行轻微修改。这里有一个简单的
awk
将文本从指定模式中删除:
cat file
before
/**
* @something
**/
after
当您不希望包含开始/结束模式时,这是处理此问题最简单的awk
方法之一:
awk '/END/{f=0} f; /START/{f=1}'
使用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
您可以通过更改其顺序来简化此操作。这样就不需要
next
语句了。请参阅我的帖子。sed不应用于任何多行问题,它严格适用于单行上的替换。awk并不复杂,使用它只需要一个小小的范式转换,因为默认情况下,它提供了许多您必须用其他工具/语言手工编写的功能,用于解析文本文件(例如,读取行、拆分为字段等)但是,一旦你使用过它几次,它就不会比任何其他基于Algol的语言更复杂了。你得到的答案是基于对你的需求的几种不同的解释。如果您提供一个真正具有代表性的输入文件(即至少包含两个要删除的模式的输入文件)和相关的expected output.UUOC,那么您就最有可能得到一个可靠的答案,而要成为一个可靠的解决方案,您需要的不仅仅是轻微的修改
awk -v RS='/[*][*][^/]+/' -v ORS= '1' file
foobar and morestuff