修改脚本错误

修改脚本错误

我只写几行来 grep 文件中的最小值,它给了我正确的结果,但重复行两次可以修复错误

我在做什么:

  • 查找所有文件
  • 正在删除标头
  • 使用第九列以科学记数法排序
  • 使用 awk 排序并打印后取最小的第一行
  • 我也想要打印 $i 的文件名

脚本:

#!/bin/bash

for i in `ls -v *.txt` 
do 
smallestPValue=`sed 1d $i | sort -k9 -g | head -1 | awk '{print $0}'` 

echo  $i  $smallestPValue >> smallesttPvalueAll.txt
done

输出

U1.text 4 rsxxx 1672175 A ADD 759 0.0751 4.918 1.074e-06
U1.txt 4 rsxxxx 1672175 A ADD 759 0.0751 4.918 1.074e-06
U2.txt  16 rsxxxx 596342 T ADD 734 -0.05458 -5.204 2.535e-07
U2.txt 16 rsxxxx 596342 T ADD 734 -0.05458 -5.204 2.535e-07
U3.txt 2 rsxxxx 12426 T ADD 722 0.06825 5.285 1.669e-07

我得到了几行的重复,而有些则很好,因为上面的 U3 已经出现一次,这就是我想要的。我可以通过 uniq 或 sort -u 轻松删除重复的行,但只是好奇是什么原因造成的

所需输出每行重复一次

答案1

awk如果我解释正确,你可能可以用and来做你想做的事情sort- 不需要循环,或者解析 ls(微妙的提示:不要那样做!), 或headsed.

awk 'FNR > 1 {print FILENAME, $0}' *.txt | sort -k10 -g | sort -u -k1,1

这会跳过每个文件的第一行,然后打印以文件名和空格(awk 的默认输出记录分隔符或ORS)为前缀的所有剩余行。然后它通过排序对字段 10 进行通用数字排序。最后,它仅对第一个字段(文件名)进行唯一排序-k1,1,以便仅输出具有该文件名的第一行。

请注意,我们必须在此处对字段 10 进行排序,而不是字段 9,因为我们已将文件名添加为第一个字段,因此所有其他字段编号都会增加 1。

FNRFILENAME是内置 awk 变量。 FNR 是当前文件的行号(awk-lingo 中的“输入记录号”),FILENAME 是当前文件名。


这是另一种方法,这次仅使用awk

#!/usr/bin/awk -f

FNR > 1 && (! s[FILENAME] || $9 < s[FILENAME]) {
  s[FILENAME]=$9;
  l[FILENAME]=$0
};

END {
  for (f in s) {
    print f, l[f]
  }
}

将其另存为,例如smallest-pvalue.awk,使其可执行chmod +x smallest-pvalue.awk并运行为./smallest-pvalue.awk *.txt

此 awk 脚本在名为 的数组中跟踪每个输入文件的字段 9 的最小值,s并将匹配的输入行保存在 array 中l

处理完所有文件后,它会打印出文件名和包含每个文件的最小第 9 个字段的行。

相关内容