使用正则表达式提取子字符串,同时排除某个短语

时间:2013-05-10 08:34:08

标签: regex unix grep

说出字符串:

test.1234.mp4 

我想提取数字 1234 没有提取mp4中的4

正则表达式会是什么?

数字并不总是在第二个位置,可以位于不同的位置,也可能不总是四位数。我想提取数字而不提取mp4中的4。

更多例子:

test.abc.1234.mp4
test.456.abc.mp4
test.aaa.bbb.c.111.mp4
test.e666.123.mp4

基本上只提取数字。因此,对于最后一个例子,来自e666的666不会被提取,只有123。 提取我一直在使用

echo "example.123.mp4" | grep -o "REGEX"

编辑:test456本来是test.456

6 个答案:

答案 0 :(得分:5)

cut可以成功:

$ echo "test.1234.mp4" | cut -d. -f2
1234

,其中

cut   -d'.'        -f2
      delimiter    2nd field

如果您提供更多示例,我们可以改善输出。使用当前代码,您可以在something中提取任何blablabla.something.blablabla


更新:从您的问题更新中我们可以执行此操作:

grep -o '\.[0-9]*\.' | sed 's/\.//g'

试验:

$ echo "test.abc.1234.mp4
test456.abc.mp4
test.aaa.bbb.c.111.mp4
test.e666.123.mp4" | grep -o '\.[0-9]*\.' | sed 's/\.//g'
1234
111
123

答案 1 :(得分:5)

接受的答案将在“test.e666.123.mp4”(打印666)上失败。

这应该有效

$ cat | perl -ne '/\.(\d+)\./; print "$1\n"'
test.abc.1234.mp4
test.456.abc.mp4
test.aaa.bbb.c.111.mp4
test.e666.123.mp4
1234
456
111
123

请注意,这只会打印第一组数字,如果我们有test.123.456.mp4,则只打印123.

我们的想法是匹配一个点后跟我们感兴趣的数字(保存匹配的括号),然后是另一个点。这意味着它将在123.mp4上失败。

要解决此问题,您可以:

$ cat | perl -ne '/(^|\.)(\d+)\./; print "$2\n"'
test.abc.1234.mp4
test.456.abc.mp4
test.aaa.bbb.c.111.mp4
test.e666.123.mp4
781.test.mp4
1234
456
111
123
781

第一场比赛是线的开头(^)或点,后跟数字和点。我们在这里使用$ 2,因为$ 1是一行或一个点的开头。

答案 2 :(得分:1)

grep -Po "(?<=\.)\d+(?=\.)"

答案 3 :(得分:1)

echo "test.1234.mp4" | perl -lpe 's/[^.\d]+\d*//g;s/\D*(\d+).*/$1/'

或:

echo "1321.test.mp4" | perl -lpe 's/.*(?:^|\.)(\d+)\..*/$1/'
默认情况下,

p是打印的,因此我们不需要显式printe说我们有一个表达式,而不是一个脚本文件 l放置换行符

如果您在名字的第一部分有一个数字,这些也可以使用。

答案 4 :(得分:0)

perl -F'\.' -lane 'print "$F[scalar(@F)-2]" if(/\d+\.mp4$/)' your_file

测试:

> perl -F'\.' -lane 'print "$F[scalar(@F)-2]" if(/\d+\.mp4$/)' temp
1234
111
123

答案 5 :(得分:0)

$ cat file
test.abc.1234.mp4
test.456.abc.mp4
test.aaa.bbb.c.111.mp4
test.e666.123.mp4

$ sed 's/.*\.\([0-9][0-9]*\)\..*/\1/' file
1234
456
111
123