shell 替换文件中从string1到string2的所有内容,包括换行符

6tqwzwtp  于 7个月前  发布在  Shell
关注(0)|答案(3)|浏览(93)

我有一个文件,内容如下:
(标记为js只是为了更好的可读性,可以是任何纯文本文件)

some text
/*%SKIP% line comment %SKIP%*/
some text
/*%SKIP%
block
comment
I could contain everything except the end sequence
%SKIP%*/
some text

字符串
现在我想删除/*%SKIP%%SKIP%*/之间的所有内容,这样文件就包含:

some text
some text
some text


结果文件中是否存在空行并不重要,但最好是在删除内容的位置没有空行。我能够用sed对单行进行归档,但在多行内容时失败了。
我想这应该没什么关系,但是作为一个旁注:“start”和“end”字符串是可变的,存储在bash变量open_tag=/*%SKIP%close_tag=%SKIP%*/中。
唯一的限制是使用大多数Linux发行版上通常预装的工具,所以sedawkperlgrep都应该没问题。
我该如何实现这一点?

mrphzbgm

mrphzbgm1#

使用perl一行程序:

$ cat input.txt
some text
/*%SKIP% line comment %SKIP%*/
some text
/*%SKIP%
block
comment
I could contain everything except the end sequence
%SKIP%*/
some text
$ perl -0777 -pe 's{\R?/\*%SKIP%.*?%SKIP%\*/}{}sg' input.txt
some text
some text
some text

字符串
这将一次读取整个文件(-0777、perl 5.36.0及更新版本可以使用-g),并替换每个SKIP块(可选,前面有换行符;使用.*?进行非贪婪匹配,因此它不会匹配第一个/*%SKIP%和最后一个%SKIP%*/之间的所有内容,s选项允许.匹配换行符(g意味着像sed中一样每次匹配)。

omhiaaxx

omhiaaxx2#

使用awk

$ awk '/\/\*%SKIP%/,/%SKIP%\*\//{next}1' file
some text
some text
some text

字符串

hm2xizp9

hm2xizp93#

使用GNU awk和适当的regex作为字段分隔符。FS基本上是:

/*%SKIP%[^(%SKIP%*/)*]%SKIP%*/

字符串
即开始标记,除了结束标记之外的任何标记,结束标记:

$ gawk 'BEGIN {
    RS="^$" # slurp the file in, it is now a single big record
    FS="/\\*%SKIP%([^%]|%(%|S(%|K(%|I(%|P%(SKIP%)*(%|*%|S(%|K(%|I%)))))))*([^S%]|S([^K%]|K([^I%]|I([^P%]|P([^%]|%(SKIP%)*([^S%*]|*[^%/]|S([^K%]|K([^I%]|I([^P%]|P[^%]))))))))))*(%(%|S(%|K(%|I(%|P%(SKIP%)*(%|*%|S(%|K(%|I%)))))))*(S((K(IP?)?)?|KIP%(SKIP%)*(*|S(K(IP?)?)?)?))?)*%SKIP%\\*/"
    OFS=""  # set OFS to empty
}
{
    $1=$1   # rebuild the record ie. replace field separators
    print   # and output
}' file


输出量:

some text

some text

some text


空行是%SKIP%*/后面的新行。
它可能会或可能不会修复正则表达式在其他awk上的工作。我尝试了几个,失败和失去耐心。我在摆弄正则表达式和grep -z -v -o,但首先,后两个开关不能很好地合作。

相关问题