使用 sed 提取数字

Extracting numbers with sed

输入

...
...
PANO_20190917_185957.jpg
BURST20201216180114905_COVER.jpg
BURST20201214164624071_COVER.jpg
IMG_20190317_112951.jpg
IMG_20190317_112939.jpg
IMG_20190317_112936.jpg
IMG_20190317_112947.jpg
IMG_20200326_013746.jpg
...
...

塞德

$ fd . ./ -t f | sed  -E 's/.*\([0-9]\{1,6\}\).*//'  
sed: -e expression #1, char 26: invalid reference  on `s' command's RHS

期望的输出

...
...
201909
202012
202012
201903
201903
201903
201903
202003
...
...

还有其他方法吗?我整天都在努力让这个工作...

您可以使用这个 sed:

sed -E 's/^[^0-9]*([0-9]{1,6}).*//' file

201909
202012
202012
201903
201903
201903
201903
202003

正则表达式解释:

  • -E: 启用扩展程序正则表达式模式 (ERE)
  • ^: 开始
  • [^0-9]*:匹配0个或多个非数字
  • ([0-9]{1,6}): 匹配第一个捕获组中的 1 到 6 个数字
  • .*:匹配0个或多个任意字符

你的命令有几个问题:

  1. -E 使 sed 将您的正则表达式视为 POSIX ERE,但它遵循的语法是 POSIX BRE,
  2. 你用 .* 贪婪地匹配所有文本,下一个数字匹配模式总是只匹配一个数字,因为它可以匹配一个数字,
  3. 您希望输出中正好有 6 位数字,但您允许 1 到 6。

您可以使用以下 POSIX BRE 解决方案:

sed  -n 's/[^0-9]*\([0-9]\{6\}\).*//p'

参见 online demo 其中

  • -n 抑制默认行输出
  • [^0-9]*\([0-9]\{6\}\).* 匹配除数字以外的零个或多个字符,然后将恰好 6 位数字捕获到第 1 组,然后匹配字符串的其余部分,并且
  • </code> - 用第 1 组值替换整个匹配</li> <li><code>p - 打印替换结果。