文件Linux Shell中的列操作

时间:2012-03-19 01:27:18

标签: linux bash awk

我有一个文件,其中的条目由空格分隔。例如:

example.txt中

24676 256 218503341 2173
13236272 500 1023073758 5089
2230304 96 15622969 705
0 22 0 526
13277 28 379182 141

我想在命令行中打印“第1列/第3列”或“simila”的结果。我相信它可以用awk完成。但是,有些条目为0,因此除以0给出:

  

致命:除零尝试

在更高级的情况下,我想找到分部的中值(或某个百分位数)。

2 个答案:

答案 0 :(得分:3)

有许多方法可以忽略具有零除数的行,包括:

awk '$3 != 0 { print $1/$3 }' your-data-file

awk '{ if ($3 != 0) print $1/$3 }' your-data-file

问题改变了 - 改为打印0。答案并不难:

awk '{ if ($3 != 0) print $1/$3; else print 0 }' your-data-file

中位数和其他百分位数要处理得更为谨慎。如果数据按排序顺序最简单。我希望使用数字排序然后从那里处理数据这么容易。


我挖出了一个旧的shell脚本来计算描述性统计数据 - 单个数据数据列的最小值,最大值,模式,中值和十进制:

:   "@(#)$Id: dstats.sh,v 1.2 1997/06/02 21:45:00 johnl Exp $"
#
#   Calculate Descriptive Statistics: min, max, median, mode, deciles

sort -n $* |
awk 'BEGIN { max = -999999999; min = 999999999; }
    {   # Accumulate basic data
        count[$1]++;
        item[++n] = $1;
        if ($1 > max) max = $1;
        if ($1 < min) min = $1;
    }
END {   # Print Descriptive Statistics
        printf("# Count = %d\n", n);
        printf("# Min = %d\n", min);
        decile = 1;
        for (decile = 10; decile < 100; decile += 10)
        {
            idx = int((decile * n) / 100) + 1;
            printf("# %d%% decile = %d\n", decile, item[idx]);
            if (decile == 50)
                median = item[idx];
        }
        printf("# Max = %d\n", max);

        printf("# Median = %d\n", median);
        for (i in count)
        {
            if (count[i] > count[mode])
                mode = i;
        }
        printf("# Mode = %d\n", mode);
    }'

minmax的初始值并非完全科学。它有助于说明一点。

(这个1997版本几乎与它的1991年版本相同 - 除了版本信息行之外所有版本都是相同的。所以,代码已经超过20年了。)

答案 1 :(得分:2)

这是一个解决方案:

awk '
  $3 != 0 { vals[$NR]=$1/$3; sum += vals[$NR]; print vals[$NR] }
  $3 == 0 { vals[$NR]=0; print "skipping division by 0" }
  END { sort vals; print "Mean = " sum/$NR ", Median ~ " vals[$NR/2] }
  ' < your_file

如果3 rd 列不为零,这将计算,打印和累积商。当它到达你的文件的末尾(应该有一个空行)时,它将打印所有商的均值和中位数,假设它将除以零的每一行为0

awk中,$n表示n th 字段,以1开头,$NR表示记录数(即,已处理的行数)。每个商都存储在数组vals中,使我们能够计算中值。

在现实生活中,中位数被定义为给定奇数元素的“中间”项目,或者给定偶数元素的两个“中间”项目的平均值。

在实施sort功能时,你自己就可以了!