【问题标题】:Delete string after '#' using sed使用 sed 删除 '#' 后的字符串
【发布时间】:2019-08-26 08:30:32
【问题描述】:

我有一个看起来像这样的文本文件:

#filelists.txt
a
# aaa
b
#bbb
c #ccc

我想删除以'#'开头的部分行,然后,如果行以#开头,则删除整行。

所以我在 shell 中使用 'sed' 命令:

sed -e "s/#*//g" -e "/^$/d" filelists.txt

我希望它的结果是:

a
b
c

但实际结果是:

filelists.txt
a
 aaa
b
bbb
c ccc

我的“sed”命令出了什么问题?

我知道 '*' 表示“任何”,所以我认为 '#*' 表示“#”之后的字符串。

不是吗?

【问题讨论】:

  • #* 表示零个或多个#。要完成这项工作,您需要#.* 其中. 表示任何字符,然后星号给出零个或多个任何字符。

标签: sed


【解决方案1】:

你可以使用

sed 's/#.*//;/^$/d' file > outfile

s/#.*// 删除 # 和该行的所有其余部分,/^$/d 删除空行。

查看online test

s="#filelists.txt
a
# aaa
b
#bbb
c #ccc"

sed 's/#.*//;/^$/d' <<< "$s"

输出:

a
b
c 

另一个想法:匹配具有# 的行,然后删除# 和该行的其余部分,如果该行为空,则删除:

sed '/#/{s/#.*//;/^$/d}' file > outfile

another online demo

这样,您可以保留原来的空行。

【讨论】:

  • 嗨@Wiktor Stribiżew:做';'相当于'sed -e'?
  • @curlywei 嗯,我理解为动作序列算子,右边的操作是在左边的操作之后进行的。
【解决方案2】:

* 并不意味着“任何”(至少在正则表达式上下文中不是)。 * 表示“零个或多个前面的模式元素”。这意味着您正在删除“零个或多个#”。因为你只有一个#,你把它删了,剩下的那行就原封不动了。

您需要s/#.*//:“删除# 后跟零个或多个任意字符”。

编辑:建议grep -v,但没有注意到第三个示例(行中间的#)。

【讨论】:

  • 嗨@Amadan:“。”的 ”#。”意思是“后跟零个或多个任意字符”
  • . 只是“任何字符”。 .* 是“零个或多个任意字符”。
  • #. 表示# 之后的第一个,#.. 表示# 之后的2 个字符,#.* 表示# 之后的许多字符
猜你喜欢
  • 2017-05-28
  • 2020-11-03
  • 1970-01-01
  • 2011-03-07
  • 1970-01-01
  • 2012-04-09
  • 2023-03-11
  • 2023-03-23
  • 1970-01-01
相关资源
最近更新 更多