SED删除注释,但保留特定的否定注释字符串

SED删除注释,但保留特定的否定注释字符串,sed,comments,negation,Sed,Comments,Negation,我正在尝试从文件中删除注释,但重要的是我想保留特定字符串: ## Something # START # END 这些必须保留rest而不是注释行,我想用“d”删除rest——这很重要。我不想使用打印否定或其他技巧,因为这个sed命令稍后还会使用额外的“-e”处理其他事情 以下是示例文件: # START group1: user1@domain.com, user2@domain.com, user3@domain.com group2: user3@domain.com, user4@do

我正在尝试从文件中删除注释,但重要的是我想保留特定字符串:

## Something
# START
# END
这些必须保留rest而不是注释行,我想用“d”删除rest——这很重要。我不想使用打印否定或其他技巧,因为这个sed命令稍后还会使用额外的“-e”处理其他事情

以下是示例文件:

# START
group1: user1@domain.com, user2@domain.com, user3@domain.com
group2: user3@domain.com, user4@domain.com

# S
#STAR
# start
# star
# comment is here
## Owner1
group3: user1@domain.com, user3@domain.com

## Owner2
group4: user4@domain.com, user3@domain.com

group3: user2@domain.com, user3@domain.com

# END

group5: user4@domain.com
alias1: user6@domain.com
我尝试使用如下命令:

sed -e '/^#[^#]/d' sample.file
这会删除以“#”开头的每一行,而下一个字符不是“#”,因此会留下“##”行,但如何在不丢失#开始行和#结束行的情况下删除其余行

我需要在没有管道的同一命令中执行此操作,“!p”或“p”版本它必须是此“d”修改版本。 尝试了以下方法:

sed -e '/^#[^#][^S][^T][^A][^R][^T]/d'

但是没有什么是我想要的。 我不确定这样做是否可行

预期产出:

# START
group1: user1@domain.com, user2@domain.com, user3@domain.com
group2: user3@domain.com, user4@domain.com

## Owner1
group3: user1@domain.com, user3@domain.com

## Owner2
group4: user4@domain.com, user3@domain.com

group3: user2@domain.com, user3@domain.com

# END

group5: user4@domain.com
alias1: user6@domain.com
问候和感谢帮助:)

试试:

sed -E '/^##|^# START|^# END/bskip; /^#/d; :skip' file
例子 工作原理
  • /^##|#|#开始| |#结束/bskip

    对于与
    ^##
    ^#START
    ^#END
    匹配的任何行,我们将分支到标签
    skip

  • /^#/d

    对于以
    #
    开头的所有其他行,我们将删除

  • :跳过

    这定义了标签
    跳过

BSD/macOS 以上内容已通过GNU sed进行了测试。对于BSD/macOS sed,请尝试:

sed -E -e '/^##|^# START|^# END/bskip' -e '/^#/d' -e ':skip' file

这比John1024s的答案更详细,但也有效:

sed -r 's/# ((START)|(END)).*/## \1/;/^#[^#].*/d;s/## ((START)|(END))/# \1/;' sample.conf
将#开始/结束注释转换为受保护的#格式,然后进行转换,然后将其转换为#开始/结束返回

首先我监督了“no-/p”要求,然后显而易见的解决方案是:

sed -r '/# (START)|(END).*/p;/^#[^#].*/d' sample.conf 
您可以使用简单的打印模式/p,而不是删除复杂的删除模式/d


请注意,
[^S][^T][^A][^R][^T]
将匹配“
END
”(后面有两个空格-可能不太可能,但如果另一个3或5个字母的异常需要处理,如果它没有被读取,它会变得难看。

请提供更多的代码上下文以演示您施加的限制。例如,显示一些虚拟的“附加-e”.Hoe关于使用awk/gawk而不是sed的问题?通过这种方式来满足您的标准可能会更容易、更易读。可能会显示一些基本上按照要求进行编码的尝试版本,但会记录您的次要要求。理想情况下,会显示哪些不适用于它们。我已经监督了“无p”要求。您能解释一下吗有问题吗?您好,这似乎有效,但请告诉我这个-E似乎与-E不同,并且可能不会在所有linux系统上都受支持?我想这只是为了更干净的“或”=“|”似乎这也起作用了:sed-e'/^##| | | | | | | | |结束/bskip;/^#/d;:skip.谢谢!@mike是的,这是完全正确的:
-e
调用扩展正则表达式,在我们的例子中,它允许
代替
\
,而且,是的,没有
-e
的版本也会起作用。我认为
-r>在linux上完成这项工作。谢谢:)是的,没错<代码>-r
将与现代和古代GNU-sed一起使用。然而,对于扩展正则表达式,POSIX似乎已经决定使用
-E
而不是
-r
。因此,所有现代版本的GNU都使用
-E
来启用扩展正则表达式。在BSD/macOS上,只接受
-E
sed -r 's/# ((START)|(END)).*/## \1/;/^#[^#].*/d;s/## ((START)|(END))/# \1/;' sample.conf
sed -r '/# (START)|(END).*/p;/^#[^#].*/d' sample.conf