使用 bash 从方括号之间提取数字

use*_*326 3 python command-line bash

我的文件看起来像这样:

[581]((((((((501:0.00024264,451:0.00024264):0.000316197,310:0.000558837):0.00857295,((589:0.000409158,538:0.000409158):0.000658084,207:0.00106724
):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.
127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253
931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:
0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);  
[50]((((((((501:0.00024264,451:0.00024264):0.000316197,310:0.000558837):0.00857295,((589:0.000409158,538:0.000409158):0.000658084,207:0.00106724):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);
Run Code Online (Sandbox Code Playgroud)

每个新行都以 pattern 开头[number]。每行都以模式结束);

我需要从每一行的开头提取方括号中的数字,并将它们写入一个新文件。我事先不知道文件有多少行。

Eli*_*gan 12

您只需一个grep命令即可实现此目的。这是因为 GNU grep 允许您使用Perl 正则表达式( -P),它支持零宽度环视断言\K(?= ),在这种情况下):

grep -oP '^\[\K\d+(?=\])' infile
Run Code Online (Sandbox Code Playgroud)

如上所述,这会将输出发送到您的终端。要将其重定向到文件,请使用:

grep -oP '^\[\K\d+(?=\])' infile > outfile
Run Code Online (Sandbox Code Playgroud)

这种方法具有简洁和简单的优点。它匹配的文本

  • 前面是 ( \K)

    • 一个[字符(\[- ) \,需要的[,否则在正则表达式有特殊意义
    • 出现在行首 ( ^);
  • 由一位或+多位 ( \d)数字 ( ) 组成;

  • 后面跟着 ( (?= ))

    • 一个]字符(\]) -像[\部队]按字面匹配。


kos*_*kos 7

使用sed

  • < inputfile sed -n 's/^\[\([0-9]*\)\].*$/\1/p' > out

命令分解

  • < inputfile: 将内容重定向inputfilestdin
  • -n: 抑制输出
  • > out: 将内容重定向stdoutout

正则表达式细分

  • s: 执行替换
  • /: 启动正则表达式
  • ^: 匹配行的开头
  • \[: 匹配一个[字符
  • \(: 启动捕获组
  • [0-9]*: 匹配任意数量的数字
  • \): 停止捕获组
  • \]: 匹配一个]字符
  • .*: 匹配任意数量的任意字符
  • $: 匹配行尾
  • /:停止正则表达式/开始替换
  • \1: 替换为第一个捕获组
  • /: 停止更换
  • p: 只打印匹配的行

使用grep+ tr(如果您需要一种在 Ubuntu 和另一个grep不支持 PCRE 的操作系统上运行的方法——否则,请参阅Eliah Kagan 的grep-only 版本):

  • < inputfile grep -o '^\[[0-9]*\]' | tr -d '[]' > out

命令分解

  • < inputfilein grep: 将内容重定向inputfilestdin
  • -oin grep: 只打印匹配
  • -din tr: 删除字符
  • > outin tr: 将内容重定向stdoutout

正则表达式细分

  • ^: 匹配行的开头
  • \[: 匹配一个[字符
  • [0-9]*: 匹配任意数量的数字
  • \]: 匹配一个]字符