shell 脚本可以查找并替换与正则表达式匹配的区域内的模式吗?

shell 脚本可以查找并替换与正则表达式匹配的区域内的模式吗?

我想编写一个 shell 命令,用stdout空格替换与特定正则表达式匹配的所有段落中的所有换行符。在这里,我将段落定义为由两个或更多换行符结尾的任何文本。

具体来说,我想找到所有不以(or开头的文本段落$,并删除这些段落中的所有换行符。

例如,运行我的脚本

Aliquam erat volutpat.  Nunc ( eleifend leo vitae magna.  In (i)yd erat non orci
commodo lobortis.  Proin $ neque massa, cursus ut, gravida ut, lobortis eget,
lacus.  Sed diam.

Hello world.

(Nullam tristique diam
non turpis.



Hello
$again!

$foo
bar

应该导致

Aliquam erat volutpat.  Nunc ( eleifend leo vitae magna.  In (i)yd erat non orci commodo lobortis.  Proin $ neque massa, cursus ut, gravida ut, lobortis eget, lacus.  Sed diam.

Hello world.

(Nullam tristique diam
non turpis.



Hello $again!

$foo
bar

这可能吗?

我不介意是否存在附带损害,例如添加额外的换行符(但我也很好奇是否可以在没有附带损害的情况下完成!)。

答案1

在所有 Unix 机器上的任何 shell 中使用任何 awk:

$ awk -v RS= -v ORS='\n\n' -F'\n' '!/^[($]/{$1=$1} 1' file
Aliquam erat volutpat.  Nunc ( eleifend leo vitae magna.  In (i)yd erat non orci commodo lobortis.  Proin $ neque massa, cursus ut, gravida ut, lobortis eget, lacus.  Sed diam.

Hello world.

(Nullam tristique diam
non turpis.

Hello $again!

$foo
bar

上面的代码将在每个段落后打印一个空行,包括文件中的最后一个,即使它最初没有空行。如果这是一个问题,请告诉我们,因为很容易不这样做。

答案2

因为额外的空行并不重要

gawk 'BEGIN {RS=""} !/^[$(]/ {gsub("\n"," ")} {print;print "\n"}' 

解释。RS=""将 gawk 设置为段落模式。!/^[$(]/匹配不以(或开头的段落$gsub("\n"," ")将换行符更改为空格。print;print "\n"输出数据和换行符。

答案3

GNU sed

将段落存储在保留空间中。此方法将保留多个空行。

sed -e '
  /./,/^$/!b
  H;/./{$!d;}
  z;x;s/.//;$!s/.$//
  /^[$(]/!y/\n/ /
  $!G
' file

perl -pl -00e '
  y/\n/ / unless /^[$(]/;
  s/$/\n/ unless eof;
' file

Perl 的段落模式-00。连续的空行将被折叠为一行。

相关内容