sed:如何replace多行模式中的所有内容?

我必须从另一个创build一个SQL脚本改变他们的内容。 例如。

SELECT value INTO val FROM table WHERE condition; SELECT value2 INTO val2 FROM table WHERE condition1 OR condition2; 

所以我尝试了

 sed 's/FROM .*;/;/g' 

但这是回报

 SELECT value INTO val ; SELECT value2 INTO val2 FROM table WHERE condition1 OR condition2; 

而不是这个,这是我所需要的

 SELECT value INTO val ; SELECT value2 INTO val2 ; 

有任何想法吗? 基本上我想要做的是删除所有包含在'从'和'下';'

 sed ':load # load any multiline sequence before going further /;[[:space:]]*$/ !{ N;b load } # from here you have a full (multi)line to treat s/[[:space:]]\{1,\}FROM[[:space:]].*;/ ;/ ' YourFile 

在删除结束之前,您需要首先加载多行序列(加载段中的序列循环直到结束;找到)

  • :load :稍后使用的“goto”的地址标签
  • /;[[:space:]]*$/ :当没有结束时; 就行了(最后还是有些结局空间吧
    • N :在工作缓冲区中加载新行
    • b load :转到标签load (转到)
  • s/[[:space:]]\{1,\}FROM[[:space:]].*;/ ;/用你的新格式改变整个当前的工作缓冲区。 在这种情况下,Sed处理缓冲区而不是一行,新行在这种情况下是像其他字符。

最后一行需要以…结尾; 如果不能处理,则最后(未完成)序列丢失

我想你可以删除脚本中的'\ n',然后使用sed删除。

例如

 cat test.sql |tr -d '\n'|sed 's/FROM [^;]*;/;\n/g' 

awk是基于记录的,而不是基于行的sed,所以处理多行字符串没有问题:

 $ awk 'BEGIN{RS=ORS=";"}{gsub(/FROM .*/,"")}1' file SELECT value INTO val ; SELECT value2 INTO val2 ; 

以上只是将记录分隔符设置为a ; 而不是默认的换行符,并对结果字符串进行操作,该字符串可以像任何其他字符一样包含换行符。

据我所知,你必须摆脱换行符分隔符

 tr -d '\n' 

或者在re.compile中使用Pythons的 “re.M | re.DOTALL”参数

例如(粗略地):

 pattern = re.compile('FROM[^;]*;', re.M | re.DOTALL) result = re.findall(pattern, file) 

通常,当我需要对换行符进行regex时,我总是用Python来结束。 Bash太基于新行,很难做到这一点。 但是如果你真的需要使用bash,用占位符替换'\ n'就足够了。