我有一个文本文件,如下所示:
其中 $ 表示 EOL(行尾)位置,我用它来说明这一点。
53t83t5 5 gejgi3 gg 4gij503 $
/* rtdrfsetsrhs $
ryhrdhrh $
rhyrdhyyyyyyyyyyyrhyrshrh$
ryhrhrh */$
$
345dfeb terfgb$
/*srdtfgyhgfs*/ $
$
$
现在我必须将此/* */
块的每一行替换为位于行开头的 EOL,如下所示,注意 $ 的位置3号线/*
这意味着如果有一些字符包括空格,我们不应该跳过它,而是应该将 EOL 放在正斜杠的位置。
53t83t5 5 gejgi3 gg 4gij503 $
$
$
$
$
$
345dfeb terfgb$
/*srdtfgyhgfs*/ $
$
$
我能够使用甚至删除整个块来检测该块sed '/\/\*/,/\*\//d inputFile
,但我想知道我们是否可以在 .sed 脚本中使用 sed 命令执行上述操作。
笔记: /*...*/
这用于说明模式块,我们也可以有不同的模式封闭块,例如<--...-->
或者!!...!!
但是我想知道 的片段/*...*/
,我可以自己处理所有其他的。
答案1
从您的预期输出来看,您似乎想要从至少包含一个换行符的块中删除除换行符之外的所有字符。
所以你可以使用perl
:
perl -0777 -pe '
s{/\* .*? \*/ | <-- .*? --> | !! .*? !!}{
$& =~ /\n/ ? $& =~ s/[^\n]//gr : $&
}gsex' < your-file
答案2
如果必须是sed
,以下脚本将按照您的示例执行操作:
#!/usr/bin/sed -f
# if line contains "/*" we enter our "within-patterns" code-block
/\/\*/{
# however, lines must also _not_ contain "*/",
# because our specs wants us to leave those lines as is
/\*\//!{
# first line within patterns, delete everything after the "/*"
s%/\*.*%%
# this is a label to be used by "goto" (sed's 'b' command)
:block
# display current line and read next one
n
# if line just read does _not_ have "*/" end-of-block
/\*\//!{
# delete whole line and
s/.*//
# "goto" label "block" above
bblock
}
# we get here if current line _does_ contain "*/" end-of-block,
# in which case we delete everything up to the "*/"
s%.*\*/%%
# then exit our "within-patterns" code-block.
}
}
该方法是让脚本在“块内”模式下保持对循环的控制,而不是让它sed
自动执行。通过这种方式,我们可以微调块内线条的操作。
但请注意,这仅用于教学目的,因此要介绍一点点更先进的sed
构造。该脚本并不完全适合从实际的 C/XML/HTML/任何源文件中解析注释行,因为这些文件通常比示例场景复杂得多。参见例如此问答以获得更多见解。