首页 > 解决方案 > 使用 awk 创建的 bash 变量在 echo 输出中移动

问题描述

我的 while 循环正在读取一个看起来像这样的文件:

Chr start stop value  
chr1 12345 4345666 -1 

与另一个文件进行比较以创建这些值的平均值 (probes.txt):

chr1 12345 12345 0.124  
chr1 12346 12346 0.421

现在代码如下:

$file | while read line
do 
first=$(echo $line | awk '{print $1}' )
second=$(echo $line | awk '{print $2}')
third=$(echo $line | awk '{print $3}')
logsum=$(awk -v first=$first  -v second=$second -v third=$third '$1==first && $2>= second && $3<=third { sum += $4; n++} END { print sum / n; }' probes.txt
echo "$line" "$logsum"
done

我期望的输出是:

chr1 12345 4345666 -1 0.232

但相反,$logsum 最终出现在 $line 的前面覆盖部分:

 0.232345 4345666 -1 0.232

我也尝试过 printf 并遇到同样的问题

printf "%s %s \n" "$line" "$logsum"

我认为问题是 $logsum 变量,因为如果我看起来没问题

echo "$logsum" "$line"

反而。

有谁知道这里发生了什么以及如何解决它?

编辑我正在使用 Mac 以防这是一个问题

用dos2unix修复

标签: bashvariablesawk

解决方案


除了\r\n按照@kvantour 的建议检查字符外,我建议在一个 AWK 脚本中完成所有这些工作。这样会更有效率。

假设,如果您将其保存到script.awk

NR == 1 { print $0,"logsum"; next }
{
    sum = 0; n = 0; avg = 0;
    while(( getline line < fn) > 0) { 
            split(line, arr);
            if (arr[1]==$1 && arr[2]>=$2 && arr[3]<=$3) {
                    sum += arr[4]; n++;
            }
    }
    if (n>0) avg = (sum / n);
    print $0, avg;
}

你可以这样称呼它:

awk -v fn=probes.txt -f script.awk YOURFILE.txt

示例输出:

Chr start stop value logsum
chr1 12345 4345666 -1 0.2725

推荐阅读