【问题标题】:How to get only lines with a single quote using GNU sed in Bash shell?如何在 Bash shell 中使用 GNU sed 仅获取带有单引号的行?
【发布时间】:2025-12-14 05:10:01
【问题描述】:

我正在编写一个脚本来解析一个文本文件(多行)。我只需要打印符合以下模式的行:

  1. 该行的第一个字符是大写字母
  2. 该行的第二个字符是小写字母或单引号
  3. 该行的第三个字符是小写字母或空格

“有效”行示例

  • Abcd
  • A'cd
  • Ab c

在 Linux 上尝试使用 GNU sed 4.2.2

I ] 第一次尝试(转义)

$ html2text foo.html | sed -r "/^([A-Z][a-z\'])/!d"

产生以下错误消息:

html2text foo.html | sed -r "/^([A-Z][a-z\'])/日期"

sed:-e 表达式 n°1,字符 19:命令后的额外字符

II ] 第二次尝试(不转义)

$ html2text foo.html | sed -r "/^([A-Z][a-z'])/!d"

产生以下错误消息:

html2text foo.html | sed -r "/^([A-Z][a-z'])/日期"

sed:-e 表达式 n°1,字符 18:命令后的额外字符

我不太确定如何处理范围内的单引号“'”。我知道根本不支持在单引号 sed 表达式中转义单引号,但这里两个 sed 表达式都是双引号。

奇怪的是错误消息都返回“.../date”(错误消息的第一行),这似乎是一个错误或解析问题(“/!d”标志被误解了)...

注意:html2text 将 'foo.html' 转换为文本文件。 sed -r 选项代表扩展正则表达式。 "[A-Z]" 匹配一系列字符(方括号在这里不是文字)

感谢您的帮助

【问题讨论】:

  • 你为什么不用grep?
  • 您的前两个有效示例只有两个字符.. 他们如何满足#3?或者它应该是一个空间?
  • 实际上,您的有效行与您在步骤中声明的不匹配,因为您声明了 3 个字符长并且您的前两个样本仅包含两个
  • FatalError,Fede:你说得对,我一直很懒... 有效行示例现已修复。
  • 如果您的本地化确实在其错误消息中打印° 代替º,您应该提交针对sed 的错误报告。

标签: regex linux bash sed quoting


【解决方案1】:

正如casimir-et-hippolyte 所指出的,在这里使用 grep 更简单:

grep "^[A-Z][a-z'][a-z ]"

或使用 sed:

sed -n "/^[A-Z][a-z'][a-z ]/p"

【讨论】:

  • @jineff:我错过了显而易见的事情,谢谢。仍然很好奇为什么 !d 标志似乎会产生这些错误。
  • 最佳解释(“!d”问题):thegeekstuff.com/2011/08/bash-history-expansion
  • 要便携工作,您应该使用字符类 - [[:upper:]] 而不是 [A-Z][[:lower:]'] 而不是 [a-z']。这将尊重对命令有效的LC_CTYPE
  • @jineff:我猜是使用双引号导致 !d 在我的 Bash 历史记录中扩展为“日期”命令。 karakfa 答案 (*.com/a/32255448/998155) 在这种情况下确实非常有用
【解决方案2】:

如果由于某种原因需要单引号,这可以用来转义脚本中的单引号

sed -n '/^[A-Z][a-z'"'"'][a-z ]/p'

【讨论】: