【问题标题】:awk: math operations of multi-column data in multiple CSV filesawk:多个 CSV 文件中多列数据的数学运算
【发布时间】:2021-08-01 23:08:17
【问题描述】:

我正在编写循环多列数据填充并执行集成 AWK 代码以对多列数据进行操作的 bash 脚本。

#!/bin/bash
home="$PWD"
# folder with the outputs
rescore="${home}"/rescore 
# folder with the folders to analyse
storage="${home}"/results
    

while read -r d; do
awk -F ", *" '                  # set field separator to comma, followed by 0 or more whitespaces
FNR==1 {
   if (n) {                     # calculate the results of previous file
     f=                   # apply this equation to rescore data using values of $3 and $2
      f[suffix] = f          # store the results in the array
      n=$1 # take ID of the column
   }
   prefix=suffix=FILENAME
   sub(/_.*/, "", prefix)
   sub(/\/[^\/]+$/, "", suffix)
   sub(/^.*_/, "", suffix)
   n = 1                        # count of samples
   min = 0                      # lowest value of $3 (assuming all $3 < 0)
}
FNR > 1 {
   s += $3
   s2 += $3 * $3
   ++n
   if ($3 < min) min = $3       # update the lowest value
}
   print "ID" prefix, rescoring
   for (i in n)
      printf "%s %.2f\n", i, f[i]
}'  "${d}_"*/input.csv > "${rescore}/"${d%%_*}".csv"
done < <(find . -maxdepth 1 -type d -name '*_*_*' | awk -F '[_/]' '!seen[$2]++ {print $2}')

简而言之,工作流应该处理位于 ${d} 文件夹中的 input.csv 的每一行,这些行已被我的 bash 脚本正确识别:

# input.csv located in the folder 10V1_cne_lig12
ID, POP, dG
1, 142, -5.6500 # this is dG(min)
2, 10, -5.5000
3, 2, -4.9500
4, 150, -4.1200

我的 AWK 脚本预计会处理每个 CSV 文件的每一行,以便将它们减少到两列,并保留在输出中:i) input.csv 第一列中的数字(包含已处理的 ID line) + 包含 CSV 文件的文件夹名称 ($d) 以及 ii) 应用于 input.csv 的 POP 和 dG 列中的数字的数学运算 (f) 的结果:

f(ID)= sqrt(((dG(ID)+10)/10)^2+((POP(ID)-240)/240))^2)

其中 dG(ID) 是 input.csv 的“重新评分”行的 dG ($3) 的值,POP(ID) 是其 POP 值 ($2)。最终 output.csv 包含有关 1 个输入的信息。 csv 应采用以下格式:

# output.csv
ID,             rescore value
1 10V1_cne_lig12,  f(ID1)
2 10V1_cne_lig12,  f(ID2)
3 10V1_cne_lig12,  f(ID3)
4 10V1_cne_lig12,  f(ID4)

虽然我的代码的 bash 部分(处理不同目录中的 CSV 循环)正常工作,但我仍然坚持使用 AWK 代码,它没有正确分配行的 ID,以便我可以应用演示的数学运算使用具有精确 ID 的行的 $2 和 $3 列。

【问题讨论】:

  • “10V1_cne_lig12”从何而来?
  • 所有文件夹(包含 input.csv)都位于 $storage 中,它已在 bash 部分中定义(并且它工作正常!)从字面上看,我们在 bash 中循环 $storage 中的许多文件夹(每个每个都包含一个三列 input.csv 文件),然后为每个 csv.file 应用 AWK 代码
  • 我们不知道您的数据。我们只看到您在此处发布的内容。您打算在哪里提取该字符串?是不是文件名,现有字段之一,需要从其他字段中派生出来,常量?
  • 实际上应该直接提取并在第一列的 ID 附近提及的文件夹的名称(包含 csv)...但为简单起见,您可能只写一个 AWK 部分的示例,仅关注关于数学方程,因为它可能只应用于一个 csv 文件来处理它的第二列和第三列......非常感谢提前!

标签: bash math awk


【解决方案1】:

给定输入文件:文件夹/文件

ID, POP, dG
1, 142, -5.6500 
2, 10, -5.5000
3, 2, -4.9500
4, 150, -4.1200

这个脚本

$ awk -F', *' -v OFS=', ' '
        FNR==1 {path=FILENAME; sub(/\/[^/]+$/,"",path); print $1,"rescore value"; next} 
               {print $1" "path, sqrt((($3+10)/10)^2+(($2-240)/240)^2)}' folder/file

会产生

ID, rescore value
1 folder, 0.596625
2 folder, 1.05873
3 folder, 1.11285
4 folder, 0.697402

不确定你的代码的其余部分是做什么的,但我想你可以把它集成进去。

【讨论】:

  • 好的,谢谢!现在 AWK 部分工作得很好!一个问题 - 是否可以通过管道(以便我可以选择使用它来对我的数据进行基准测试)你的 AWK 解决方案到 sed 之类的东西,它将进一步过滤输出并将其减少到一行:只保留标题中的第一列(第 1 行)+ 包含其最小值的行中的 dG 值 + () 中的 ID。对于我们的示例,过滤后的输出应为:ID, 0.596625 (1)。
  • 刚刚创建了一个新主题来展示我的 bash/awk 代码,以便清晰:stackoverflow.com/questions/67501145/…
猜你喜欢
  • 1970-01-01
  • 2021-07-09
  • 1970-01-01
  • 2019-01-31
  • 2021-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-30
相关资源
最近更新 更多