从带有sed的字符串返回最后[0-9] \ {6 \}

时间:2012-11-24 20:55:22

标签: regex sed pattern-matching

我想以

的形式传递一长串文件名
something_0230232_long_5160mK.csv
something_0230232_long-025160mK.csv
simething_0230342_lingk425460mK.csv

到sed(或类似的linux shell工具)并得到永远的 每行mK之前的最后一位数字

如果有正好6个数字,这是有效的。如何增加n位数呢?

echo "something_0230232_long_025160mK.csv" | sed -e "s/S.*\([0-9]\{6\}\)mK\.csv/\1/p" 

3 个答案:

答案 0 :(得分:4)

使用GNU grep的解决方案:

$ grep -Po '[0-9]+(?=mK)' file

5160
025160
425460

说明:

-o仅显示匹配行的部分。

-P使用perl regexp。

[0-9]+     # Match a string of digits (at least one)
(?=mK)     # Followed by mK (positive lookahead)

使用sed (因为您问过)

sed -E 's/.*[^0-9]([0-9]+)mK.*/\1/' file

-E使用扩展的regexp -r的别名但更具可移植性。)

s/         # Subsitution -
.*         # Match everything
[^0-9]     # That's not a digit
([0-9]+)   # Capture the last digit string
mK         # Followed by the string mK
.*         # Match everything left
/          # Replace with -
\1         # The captured digit string only
/          #  

答案 1 :(得分:1)

您使用sed命令走在正确的轨道上:

echo "something_0230232_long_025160mK.csv" |
sed -e 's/^.*[^0-9]\([0-9]\{1,\}\)mK\.csv/\1/'

的差异:

  • S替换为^。这在开始时匹配(数据中没有S,因此原始内容永远不会匹配。)
  • 6替换为1,。这意味着给定上下文的“一个或多个数字”(严格地说,前一个正则表达式的一个或多个重复,但前一个正则表达式是[0-9])。
  • 插入[^0-9]以阻止.*过于贪婪。当匹配的位数固定(\{6\})时,刚性阻止了.*过于贪婪。当你有两个灵活的范围时,第一个是最长的。如果没有[^0-9],则会为示例字符串打印0
  • 删除'p',使值打印一次。或者,保留p并添加-n作为选项。

提醒自己:在发布之前(或之后不久)进行测试。

答案 2 :(得分:0)

echo "something_0230232_long_025160mK.csv" | sed 's/^.*_//' | sed 's/mK.csv//'