【问题标题】:regex to catch substring in a line and change output with sed正则表达式捕获一行中的子字符串并使用 sed 更改输出
【发布时间】:2016-10-29 16:26:07
【问题描述】:

我正在尝试组合一个正则表达式,它将找到具有以下格式的子字符串:

  1. [a-z].*(“x”小写字母个数)
  2. '-' 符号 [a-z].*
  3. ('x' 小写字母的个数 [0-9].*
  4. ('x' 个数字从 0 到 9)

该子字符串后面的行中的任何其他内容(包括空格或',')都不会被正则表达式捕获,然后我会在结果中添加一个新行,以便它们在列表中。

如果这个正则表达式按照我想要的方式工作,那么从下面的字符串中

file.txt: hostname abcd-efg123, zfdh-eif23 , reox-bmo552, 'coor-dto201',

我会收到这个输出

abcd-efg123
zfdh-eif23
reox-bmo552
coor-dto201

这是我目前所拥有的。我正在尝试使用正则表达式,然后将结果存储为两个变量,然后我可以将它们放回 sed。我没有得到预期的结果。

我使用的正则表达式/sed 是

sed 's/\([a-z].*\)-\([a-z].*[0-9].*\)/\2 \1 \n/g'

这是直接来自提示符的命令

macbook:~ user$ echo "file.txt: hostname abcd-efg123, zfdh-eif23 , reox-bmo552, 'coor-dto201'," | sed 's/\([a-z].*\)-\([a-z].*[0-9].*\)/\2 \1 \n/g'
dto201', file.txt: hostname abcd-efg123, zfdh-eif23 , reox-bmo552, 'coor n

【问题讨论】:

  • [a-z].* 并不意味着“任意数量的小写字母”:它的意思是“一个小写字母,后跟任意数量的字符”。任何* 量词适用于前一个标记.,这是正则表达式的“小丑”,它将匹配任何字符。

标签: regex sed regex-greedy


【解决方案1】:

这是我用来匹配的正则表达式:

[a-z]*-[a-z]*[0-9]*

您的正则表达式中的主要问题是使用.*,您显然是指*。正如我所评论的,* 是表示“任意次数(包括 0)”的量词,而 . 是“任意字符”通配符。您想将量词应用于您以前的字符类而不是.. 没有理由在这里。

请注意,使用 * 包含 0 次重复,因此正则表达式将匹配单个破折号,这可能不符合您的口味。
也许你可以更具体一些,使用正则表达式:

[a-z]{4}-[a-z]{3}[0-9]{2,3}

这里我们不使用*作为量词,而是在大括号之间使用数字:它们使我们能够指定精确的重复次数(即.{4}表示“任意4个字符”)或重复范围(即[0-9]{2,6} 表示“2 到 6 位”)。您还可以使用 +,这是一个量词,意思是“至少一次”,正如 Kenavoz 所提到的。

这是我在 linux 命令中使用它的方式:

grep -o '[a-z]*-[a-z]*[0-9]*'

grep -Eo '[a-z]{4}-[a-z]{3}[0-9]{2,3}'

它在行动:

$ echo "file.txt: hostname abcd-efg123, zfdh-eif23 , reox-bmo552, 'coor-dto201'," | grep -o '[a-z]*-[a-z]*[0-9]*'
abcd-efg123
zfdh-eif23
reox-bmo552
coor-dto201

或者使用更具体的正则表达式:

$ echo "file.txt: hostname abcd-efg123, zfdh-eif23 , reox-bmo552, 'coor-dto201'," | grep -Eo "[a-z]{4}-[a-z]{3}[0-9]{2,3}"
abcd-efg123
zfdh-eif23
reox-bmo552
coor-dto201

【讨论】:

  • 谢谢,我没有考虑过使用 grep 来做。好主意。
  • 不客气。 sed 不太适合提取单行的多个部分,并且在您只需要提取数据时通常会过度使用。
  • 因为* 是零个或多个字符,-efg 将被匹配。并应用于hostname -, -, -, -,将输出所有-
  • @Kenavoz 感谢您的意见,但这正是我第二段的重点。
  • 您可以建议一个或多个字符的模式。即:grep -o '[a-z][a-z]*-[a-z][a-z]*[0-9][0-9]*' filegrep -o '[a-z]\+-[a-z]\+[0-9]\+' file
猜你喜欢
  • 1970-01-01
  • 2016-12-15
  • 2011-08-13
  • 1970-01-01
  • 2012-08-20
  • 2012-02-21
  • 1970-01-01
  • 2023-01-17
  • 1970-01-01
相关资源
最近更新 更多