Linux Shell文件中的列操作

Linux Shell文件中的列操作,linux,bash,awk,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 我想在命令行中打印“column 1/column 3”或simila的结果。我相信这可以用awk来完成。但是,有些条目为0,因此除以0得出: 致命:尝试零除 在更高级的情况下,我想找到除法的中值(或某个百分位数)。有许多

我有一个用空格分隔的文件。例如:

example.txt

24676 256 218503341 2173
13236272 500 1023073758 5089
2230304 96 15622969 705
0 22 0 526
13277 28 379182 141
我想在命令行中打印“column 1/column 3”或simila的结果。我相信这可以用awk来完成。但是,有些条目为0,因此除以0得出:

致命:尝试零除


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

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

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);
    }'
:“@(#)Id:dstats.sh,v1.2 1997/06/02 21:45:00 johnl Exp$”
#
#计算描述性统计:最小值、最大值、中值、模式、小数点
排序-n$*|
awk'开始{max=-99999999;min=999999999;}
{#积累基础数据
计数[$1]++;
项目[++n]=1美元;
如果($1>max)max=$1;
如果($1计数[mode])
模式=i;
}
printf(“模式=%d\n”,模式);
}'
min
max
的初始值并不完全科学。这说明了一点


(1997年的版本与1991年的版本几乎相同-除了版本信息行之外,其他所有代码都是相同的。因此,代码已经有20多年的历史了。)

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

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);
    }'
:“@(#)Id:dstats.sh,v1.2 1997/06/02 21:45:00 johnl Exp$”
#
#计算描述性统计:最小值、最大值、中值、模式、小数点
排序-n$*|
awk'开始{max=-99999999;min=999999999;}
{#积累基础数据
计数[$1]++;
项目[++n]=1美元;
如果($1>max)max=$1;
如果($1计数[mode])
模式=i;
}
printf(“模式=%d\n”,模式);
}'
min
max
的初始值并不完全科学。这说明了一点

(1997年的版本与1991年的版本几乎完全相同-除了版本信息行之外,其他所有代码都是相同的。因此,代码已经有20多年的历史了。)

这里有一个解决方案:

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
awk'
$3 != 0{VAL[$NR]=$1/$3;总和+=VAL[$NR];打印VAL[$NR]}
$3==0{VAL[$NR]=0;打印“跳过0除法”}
结束{sort vals;打印“Mean=”sum/$NR“,Median~”vals[$NR/2]}
“
如果第三列不为零,这将计算、打印和累加商。当它到达文件的末尾(不应该有空行)时,它将打印所有商的平均值和中位数,假设每行0除以0

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

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

实现
sort
功能时,您需要自己动手

这里有一个解决方案:

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
awk'
$3 != 0{VAL[$NR]=$1/$3;总和+=VAL[$NR];打印VAL[$NR]}
$3==0{VAL[$NR]=0;打印“跳过0除法”}
结束{sort vals;打印“Mean=”sum/$NR“,Median~”vals[$NR/2]}
“
如果第三列不为零,这将计算、打印和累加商。当它到达文件的末尾(不应该有空行)时,它将打印所有商的平均值和中位数,假设每行0除以0

awk
中,
$n
表示
n
th字段,从1开始,
$NR
表示已处理的记录数(即行数)。每个商都存储在数组<代码中