Awk 如何获取括号中的第一个元素

Awk 如何获取括号中的第一个元素,awk,sed,Awk,Sed,我有如下文件中的数据,我想提取测试精度括号内的第一个值 Intent i1 Test accuracies: (0.90, 1.0, 0.8095238095238095, 0.8947368421052632) Test average id : 1.0446857355e-06 Test average ood : 0.0693251593621 ood_train: 173 ood_test: 42 ood_val: 113 Intent i2 Test accuracies: (0

我有如下文件中的数据,我想提取测试精度括号内的第一个值

Intent i1

Test accuracies:
(0.90, 1.0, 0.8095238095238095, 0.8947368421052632)
Test average id : 1.0446857355e-06
Test average ood : 0.0693251593621
ood_train: 173
ood_test: 42
ood_val: 113

Intent i2

Test accuracies:
(0.92, 1.0, 0.8571428571428571, 0.923076923076923)
Test average id entropy: 8.82025156164e-06
Test average ood entropy: 0.0688835002447
ood_train: 173
ood_test: 42
ood_val: 113

Intent i3

Test accuracies:
(0.93, 1.0, 0.8095238095238095, 0.8947368421052632)
Test average id entropy: 2.35249270365e-07
Test average ood entropy: 0.0534607628718
ood_train: 173
ood_test: 42
ood_val: 113
我想打印“测试精度”后出现的括号后的第一个条目,如下所示:

0.90
0.92
0.93
我试图使用这个命令,但我不能一步到位

awk -F"[()]" '{print $2}' file.txt

使用GNU
grep
,您可以使用类似于

grep -Poz 'Test accuracies:\R\(\K\d[\d.]*' file.txt > outfile.txt
详细信息

  • -Poz
    -
    P
    启用PCRE正则表达式语法,
    o
    打开输出匹配模式,
    z
    允许跨换行符匹配文本(将输入和输出数据视为行序列,每个行以零字节(ASCII NUL字符)而不是换行符终止,请参阅)
  • 测试精度:
    -文字子字符串
  • \R
    -任何换行顺序(CR、LF或CRLF)
  • \(
    -a
    字符(必须以PCRE模式转义)
  • \K
    -放弃目前匹配的文本的匹配
  • \d
    -一个数字
  • [\d.]*
    -0或更多数字或
    字符
您可以这样使用
awk

awk -F'[(),]' '/^Test accuracies:$/{getline; print $2; }' file.txt > outfile.txt

这里,

  • -F'[(),]'
    将字段分隔符设置为
  • /^Test accuracity:$/
    将整行与
    Test accuracity:
    文本匹配
  • 找到该行后,
    getline
    读取下一行
  • 打印$2
    打印字段2内容
使用GNU awk:

awk -v RS='Test accuracies:\n\\(' -F, 'NR>1{print $1}' file
RS
是设置为跨两行匹配
测试精度的记录分隔符:
模式,下一行是括号

-F,
将字段分隔符设置为逗号,并允许获取括号后面的第一个字段

根据输入文件,这需要在第一次录制后完成
NR>1

这是一个非常强大的工具,支持PCRE的多行匹配模式,但不经常使用。您可以这样做

pcregrep -oM 'Test accuracies:\n\(\K([^,]+)' file

在上面的示例中,以下行适用:

awk -F "[(, )]*" '/\(/&&/\)/{print $2}'
一个更有力的例子是:

awk 'n=index($0,"("){print substr($0,n+1,index($0,",")-n-1)}'

要同时捕获数据块的名称,请尝试

awk -F"[(,]" '/^Intent/ {x=$0} /^\(/ {print x "\t" $2; x=""}' file
这是回报

Intent i1   0.90
Intent i2   0.92
Intent i3   0.93