正则表达式捕获一行中的子字符串并使用 sed 更改输出

regex to catch substring in a line and change output with sed

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

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

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

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

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

我会收到这个输出

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

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

我用的regex/sed是

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

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

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

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

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

您的正则表达式中的主要问题是使用 .*,而您显然是指 *。正如我评论的那样,* 是表示 "any number of times (including 0)" 的量词,而 . 是 "any character" 通配符。您想将量词应用于您之前的字符 class 而不是 .. 没有理由出现在这里。

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

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

这里我们没有使用 * 作为量词,而是使用大括号之间的数字:它们使我们可以指定确切的重复次数(即 .{4} 表示 "any 4 characters" ) 或一系列重复(即 [0-9]{2,6} 表示“2 到 6 位数字”)。您还可以使用 +,一个表示 "at least one time" 的量词,如 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