我只想获取可能会或可能不会 gzip 的文件的编号。但是,sed 中的正则表达式似乎不支持 ?
。这是我尝试过的:
echo 'file_1.gz'|sed -n 's/.*_\(.*\)\(\.gz\)?/\1/p'
什么也没有返回。然后我在被分析的字符串中添加了一个?
:
echo 'file_1.gz?'|sed -n 's/.*_\(.*\)\(\.gz\)?/\1/p'
得到:
1
那么,大多数正则表达式中使用的 ?
似乎在 sed 中不受支持,对吧?那么,我只想为 file_1
和 file_1.gz
提供 1
。如果执行时间很关键,在 bash 脚本中执行此操作的最佳方法是什么?
最佳答案
x?
等价于 \(x\|\)
。
但是,许多版本的 sed 支持启用“扩展正则表达式”的选项,其中包括 ?
。在 GNU sed 中,标志是 -r
。请注意,这也会更改未转义的括号以进行分组。例如:
echo 'file_1.gz'|sed -n -r 's/.*_(.*)(\.gz)?/\1/p'
实际上,您的正则表达式中还有另一个错误,即如果有的话,括号中贪婪的 .*
将吞掉“.gz”。据我所知,sed 没有等同于 *
的非贪婪算法,但您可以使用 |
来解决这个问题。 |
在 sed(和许多其他正则表达式实现)中将使用最左边的匹配项,所以你可以这样做:
echo 'file_1.gz'|sed -r 's/(.*_(.*)\.gz)|(.*_(.*))/\2\4/'
这会尝试与 .gz 匹配,只有当它不起作用时才尝试不匹配。实际上只有第 2 组或第 4 组中的一个存在(因为它们位于同一 |
的相对两侧)所以我们只需将它们连接起来以获得我们想要的值。
关于linux - 使用 ?用 sed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4348166/