简体   繁体   English

Shell脚本中的命令替换,其中替换中包含Shell变量

[英]command substitution in shell script with shell variables within the substitution

Basically the file I'm getting has the first three columns pasted into followed by a column of blanks lines because it looks like nothing is getting appended into column4 基本上,我要获取的文件的前三列已粘贴,后跟一列空白行,因为看起来好像什么都没有添加到column4中

I feel like I probably shouldn't be using the variables I created in the command substitution but I'm unsure how I would access these numbers that I need otherwise 我觉得我可能不应该使用在命令替换中创建的变量,但是我不确定如何访问否则需要的这些数字

#!/bin/sh # the first file in the expression of a bunch of patients to be made into data files that can be put into the graph
awk '{print "hs"$1,"\t",$2,"\t",$3}' $1 > temp1.txt     #important columns saved
numLines=`wc -l $1`     
touch column4.txt       #creates a column for the average of column 6-
for ((s=0;s<$numlines;s++)); do                 
        currentRow=0                            #Will eventually be the average of column 6- for the row of focus
        for ((i=6;i<=106;i++)); do              
                addition=`cut -f $i $1 | head -n $s | tail -n 1`        # cuts out the number at the row and column of focus for this loop
                currentRow=`expr $currentRow + $addition`              # adding the newly extracted number to the total
        done
        currentRow=`expr $currentRow / 101`                            #divides so the number is an average instead of a really big number
        echo $currentRow >> column4.txt                                 #appends this current row into a text file that can be pasted onto the first three columns
done
paste temp1.txt column4.txt
rm temp1.txt column4.txt

if it helps the input file is very large(about 106 columns and and tens of thousands of rows) but here's an example of what it looks like 如果它有助于输入文件很大(大约106列和数万行),但是这是一个看起来像的例子

Important identifier line grant regis 76 83 02 38 0 38 29 38 48 (..up to to 106 columns)
another important identifier bill susan 98 389 20 29 38 20 94 29 0 (.. same point)

And then output would look like (assuming we exclude the columns after ..) 然后输出看起来像(假设我们排除..之后的列)

Important identifier line 34.88
another important identifier 79.67

Sorry if something is unclear, tried my best to make it clear, just ask if there's something you're wondering about and I will edit or comment 抱歉,如果有不清楚的地方,请尽力将其弄清楚,请问是否有您想知道的地方,我将进行编辑或评论

Thank-you 谢谢

awk to the rescue! awk解救!

you can replace all with this script, using the values in the sample input 您可以使用示例输入中的值,用此脚本替换所有内容

$ awk '{for(i=6;i<=NF;i++) sum+=$i; 
        printf "%s %s %s %.2f\n", $1,$2,$3, sum/(NF-5); 
        sum=0}' file

Important identifier line 39.11
another important identifier 79.67

for median (odd number of fields) you can do this 对于中位数(奇数个字段),您可以执行此操作

$ awk '{for(i=6;i<=NF;i++) a[i-5]=$i; 
        asort(a); 
        mid=(NF-4)/2; print mid, a[mid]}' file

5 38
5 29

for even number, the general approach is taking the average of neighboring numbers (can be weighted average by distance too). 对于偶数,一般的方法是取相邻数的平均值(也可以按距离加权平均值)。

You could try to use the following: 您可以尝试使用以下方法:

perl -MList::Util=sum -lanE '@n=grep{/^\d+$/}@F; say "@F[0..4] ",sum(@n)/@n'

prints: 印刷品:

Important identifier line grant regis 39.1111111111111
another important identifier bill susan 79.6666666666667

or for with the precision 或精确

perl -MList::Util=sum -lanE '@n=grep{/^\d+$/}@F; printf "@F[0..4] %.2f\n",sum(@n)/@n'

Important identifier line grant regis 39.11
another important identifier bill susan 79.67

The above calculates the average for all numeric values in the line. 上面的内容计算了该行中所有数值的平均值。 For the exact 6- could use for example: 对于确切的6-可以使用例如:

perl -MList::Util=sum -lanE 'say "@F[0..4] ",sum(@F[5..@F])/(@F-6)'

also prints 也打印

Important identifier line grant regis 39.1111111111111
another important identifier bill susan 79.6666666666667

for printing both , the average and the median (odd or even num of elements) 用于打印两者平均和中 (奇数或偶数元素NUM)

perl -MList::Util=sum -lanE '
    @s = sort { $a <=> $b } @F[5..@F];
    $m = int(@s/2);
    printf "@F[0..4] %.2f %d\n",
    sum(@s)/(@s-1),
    (@s % 2) ? @s[$m] : sum(@s[$m-1,$m])/2
' filename

prints: 印刷品:

Important identifier line grant regis 39.11 38
another important identifier bill susan 79.67 29

and finally, the same as above - as an perl script with nice variables. 最后,和上面一样-作为带有漂亮变量的perl脚本。

use strict;
use warnings;
use List::Util qw(sum);

while(<>) {
    chomp;
    my(@text) = split;
    my(@sorted_numbers) = sort { $a <=> $b } grep { /^\d+$/ } splice @text, 5;

    my $average = sum(@sorted_numbers)/@sorted_numbers;

    my $median;
    my $mid = int(@sorted_numbers / 2);

    if( @sorted_numbers % 2) {
        $median = $sorted_numbers[$mid];
    } else {
        $median  = sum(@sorted_numbers[$mid-1,$mid])/2;
    }
    printf "@text %.2f %d\n", $average, $median;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM