sed 多个记住的模式
sed multiple remembered patterns
我有一系列类似于以下的字符串(但它们可能更复杂):
echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old"
我只想打印第一个图案 (17)。我尝试使用 sed 使用:
sed 's/.*\([0-9][0-9]\)[ y].*//'
但每次列出最后一个模式时它都会打印我(在本例中为 69)。
如何强制 sed 打印第一个或第二个模式?
谢谢!
将第一个 .*
替换为 [^0-9]*
,因为第一个 .*
会贪婪地匹配直到最后两位数字的所有字符。
sed 's/^[^0-9]*\([0-9][0-9]\)[ y].*//'
示例:
$ echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old" | sed 's/^[^0-9]*\([0-9][0-9]\)[ y].*//'
17
打印第二个数字。
$ echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old" | sed 's/^[^0-9]*[0-9][0-9][ y][^0-9]*\([0-9][0-9]\)[ y].*//'
44
或
要一一取号,
sed 's/^\([^0-9]*\([0-9][0-9]\)[ y]\)\{1\}.*//' file
只需将上述正则表达式中花括号 {}
内的 1
更改为 2
即可显示第二个数字。第三个数字改为3
,继续
示例:
$ echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old" | sed 's/^\([^0-9]*\([0-9][0-9]\)[ y]\)\{1\}.*//'
17
$ echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old" | sed 's/^\([^0-9]*\([0-9][0-9]\)[ y]\)\{2\}.*//'
44
$ echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old" | sed 's/^\([^0-9]*\([0-9][0-9]\)[ y]\)\{3\}.*//'
69
模式的问题是开始 .*
,它很贪婪,会尽可能多地消耗字符。所以在这里它会消耗直到它看到字符串中的最后一个数字。
打印第一个图案
sed -r 's/[^0-9]*([0-9][0-9])[^0-9]*([0-9][0-9]).*//'
测试
$ echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old" | sed -r 's/[^0-9]*([0-9][0-9])[^0-9]*([0-9][0-9]).*//'
17
打印第二个图案
sed -r 's/[^0-9]*([0-9][0-9])[^0-9]*([0-9][0-9]).*//'
测试
$ echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old" | sed -r 's/[^0-9]*([0-9][0-9])[^0-9]*([0-9][0-9]).*//'
44
使用grep -o
提取数字,存入一个数组,然后你可以选择你想要的:
line="I am 17 y/o, I live at 44 Main street, and my mother is 69years old" ^C
numbers=( $(grep -o '[[:digit:]]\+' <<< "$line") )
# index from the start of the array
echo "First: ${numbers[0]}"
echo "Second: ${numbers[1]}"
# index from the end of the array
echo "Last: ${numbers[-1]}"
echo "2nd Last: ${numbers[-2]}"
First: 17
Second: 44
Last: 69
2nd Last: 44
使用 GNU awk,只需定义 "pattern" 并打印它出现的数字,例如:
$ gawk -v FPAT="[0-9]{2}" '{print }' file
17
$ gawk -v FPAT="[0-9]{2}" '{print }' file
44
$ gawk -v FPAT="[0-9]{2}" '{print }' file
69
我有一系列类似于以下的字符串(但它们可能更复杂):
echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old"
我只想打印第一个图案 (17)。我尝试使用 sed 使用:
sed 's/.*\([0-9][0-9]\)[ y].*//'
但每次列出最后一个模式时它都会打印我(在本例中为 69)。
如何强制 sed 打印第一个或第二个模式?
谢谢!
将第一个 .*
替换为 [^0-9]*
,因为第一个 .*
会贪婪地匹配直到最后两位数字的所有字符。
sed 's/^[^0-9]*\([0-9][0-9]\)[ y].*//'
示例:
$ echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old" | sed 's/^[^0-9]*\([0-9][0-9]\)[ y].*//'
17
打印第二个数字。
$ echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old" | sed 's/^[^0-9]*[0-9][0-9][ y][^0-9]*\([0-9][0-9]\)[ y].*//'
44
或
要一一取号,
sed 's/^\([^0-9]*\([0-9][0-9]\)[ y]\)\{1\}.*//' file
只需将上述正则表达式中花括号 {}
内的 1
更改为 2
即可显示第二个数字。第三个数字改为3
,继续
示例:
$ echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old" | sed 's/^\([^0-9]*\([0-9][0-9]\)[ y]\)\{1\}.*//'
17
$ echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old" | sed 's/^\([^0-9]*\([0-9][0-9]\)[ y]\)\{2\}.*//'
44
$ echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old" | sed 's/^\([^0-9]*\([0-9][0-9]\)[ y]\)\{3\}.*//'
69
模式的问题是开始 .*
,它很贪婪,会尽可能多地消耗字符。所以在这里它会消耗直到它看到字符串中的最后一个数字。
打印第一个图案
sed -r 's/[^0-9]*([0-9][0-9])[^0-9]*([0-9][0-9]).*//'
测试
$ echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old" | sed -r 's/[^0-9]*([0-9][0-9])[^0-9]*([0-9][0-9]).*//'
17
打印第二个图案
sed -r 's/[^0-9]*([0-9][0-9])[^0-9]*([0-9][0-9]).*//'
测试
$ echo "I am 17 y/o, I live at 44 Main street, and my mother is 69years old" | sed -r 's/[^0-9]*([0-9][0-9])[^0-9]*([0-9][0-9]).*//'
44
使用grep -o
提取数字,存入一个数组,然后你可以选择你想要的:
line="I am 17 y/o, I live at 44 Main street, and my mother is 69years old" ^C
numbers=( $(grep -o '[[:digit:]]\+' <<< "$line") )
# index from the start of the array
echo "First: ${numbers[0]}"
echo "Second: ${numbers[1]}"
# index from the end of the array
echo "Last: ${numbers[-1]}"
echo "2nd Last: ${numbers[-2]}"
First: 17
Second: 44
Last: 69
2nd Last: 44
使用 GNU awk,只需定义 "pattern" 并打印它出现的数字,例如:
$ gawk -v FPAT="[0-9]{2}" '{print }' file
17
$ gawk -v FPAT="[0-9]{2}" '{print }' file
44
$ gawk -v FPAT="[0-9]{2}" '{print }' file
69