我想编写一个 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
。连续的空行将被折叠为一行。