3

我有一个文件,其中包含许多行,其中包含“x_y = XXXX”,其中 XXXX 可以是从 0 到某个 N 的数字。

现在,a)我想在每个这样的行中只获取该行的 XXXX 部分。b)我想得到平均值

可能这两者都在一个衬里。

我正在尝试类似的东西

cat filename.txt | grep x_y | (this need to be filled)

我不确定要归档什么过去我使用过类似的命令

perl -pi -e 's/x_y/m_n/g' 

替换 x_y 的所有实例。但是现在,我想匹配 x_y=XXXX 并取出 XXXX,然后可能对整个文件进行平均。

对此的任何帮助将不胜感激。我对 perl 和正则表达式相当陌生。

4

4 回答 4

6

Timtowtdi(像往常一样)。

perl -nE '$s+=$1, ++$n if /x_y=(\d+)/; END { say "avg:", $s/$n }' data.txt
于 2012-09-10T13:54:36.623 回答
3

以下应该做:

... | grep 'x_y=' | perl -ne '$x += (split /=/, $_)[1]; $y++ }{ print $x/$y, "\n"'

}{通俗地称为eskimo 运算符,并且因为-n放置在-e(参见perldoc perlrun) 周围的代码而起作用。

于 2012-09-10T13:33:47.433 回答
3

使用 awk:

/^[^_]+_[^=]+=[0-9]+$/ {sum=sum+$2; cnt++}
END {
    print "sum:", sum, "items:", cnt, "avg:", sum/cnt
}

$ awk -F= -f cnt.awk data.txt
sum: 55 items: 10 avg: 5.5

纯 bash 解决方案:

#!/bin/bash

while IFS='=' read str num
do
    if [[ $str == *_* ]]
    then
        sum=$((sum + num))
        cnt=$((cnt + 1))
    fi

done < data.txt

echo "scale=4; $sum/$cnt" | bc ;exit

输出:

$ ./cnt.sh 
5.5000
于 2012-09-10T13:48:45.723 回答
0

作为一个单行,与评论分开。

perl -nlwe '
    push @a, /x_y=(\d+)/g          # push all matches onto an array
    }{                             # eskimo-operator, is evaluated last
    $sum += $_ for @a;             # get the sum
    print "Average: ", $sum / @a;  # divide by the size of the array
' input.txt

将在一行中提取多个匹配项(如果存在)。

粘贴版本:

perl -nlwe 'push @a, /x_y=(\d+)/g }{ $sum += $_ for @a; print "Average: ", $sum / @a;' input.txt
于 2012-09-10T17:25:28.683 回答