作为我的 bash 例程的一部分,我使用以下集成到 bash 函数的 gawk 代码来循环 CSV 并进行分析:
test_ranking44 () {
for csv in "${rescore}"/*str*.csv; do
gawk 'BEGIN { FS=", *"; OFS=", " }
NR > 1 {
cnts[1][$1]++
cnts[2][$2]++
}
END {
numRows = 5
numCols = 2
PROCINFO["sorted_in"] = "@val_num_desc"
for (colNr=1; colNr<=numCols; colNr++) {
rowNr = 0
for (key in cnts[colNr]) {
vals[++rowNr][colNr] = sprintf("%s (number of cases: %d)", key, cnts[colNr][key])
}
}
print FILENAME, NR
print "TOP PROT", "TOP LIG"
for (rowNr=1; rowNr<=numRows; rowNr++) {
for (colNr=1; colNr<=numCols; colNr++) {
printf "%s%s", vals[rowNr][colNr], (colNr<numCols ? OFS : ORS)
}
}
}' ${csv} >> "${rescore}"/test_ranking.log
done
}
简而言之,GAWK 部分计算每个 CSV(包含字符串通过使用名称中的 glob 模式),通过关注第一列和第二列中的索引来实现。最终,它会将两列的前五个索引同时打印到 test_ranking.log 中包含的所有已处理 CSV 的信息中。是否可以直接修改 GAWK 代码,以便只考虑每个 csv 的前 N 个(即前 100 行)(现在它处理所有行)?或者我应该将其通过管道传输到 head:
for csv in "${rescore}"/*str*.csv; do
head -n 101 ${csv} | gawk 'my_code' >> "${rescore}"/test_ranking.log
done
还有其他建议吗?
答案1
你可以做
awk 'NR > 1 && NR < 101' {Your Code}
答案2
考虑更改以下部分代码,如下所示:
...
NR > 1 && NR < 101 { # Change this condition
cnts[1][$1]++
cnts[2][$2]++
}
NR == 100 { exit } # And add this exit statement
END {
...
但是,该exit
语句将阻止该行显示;将返回print FILENAME, NR
的实际行数。如果您希望以其他方式显示,只需删除该行即可。FILENAME
NR
100