Bash 将计数转换为相对概率 出身背景

Bash 将计数转换为相对概率 出身背景,bash,math,csv,text-processing,Bash,Math,Csv,Text Processing,根据单词和计数的CSV文件创建概率词典。这是文本分割问题的前奏,而不是家庭作业问题 问题 给定一个CSV文件,其中包含以下文字和计数: aardvark,10 aardwolf,9 armadillo,9 platypus,5 zebra,1 创建一个与文件中最大计数相关的概率文件: aardvark,1 aardwolf,0.9 armadillo,0.9 platypus,0.5 zebra,0.1 其中,例如,土豚1被计算为土豚10/10和鸭嘴兽,0.5被计算为鸭嘴兽5/10 问题 实

根据单词和计数的CSV文件创建概率词典。这是文本分割问题的前奏,而不是家庭作业问题

问题 给定一个CSV文件,其中包含以下文字和计数:

aardvark,10
aardwolf,9
armadillo,9
platypus,5
zebra,1
创建一个与文件中最大计数相关的概率文件:

aardvark,1
aardwolf,0.9
armadillo,0.9
platypus,0.5
zebra,0.1
其中,例如,土豚1被计算为土豚10/10和鸭嘴兽,0.5被计算为鸭嘴兽5/10

问题 实现shell脚本以创建相对概率文件的最有效方法是什么

约束条件 单词和数字都没有顺序。 没有主要的编程语言,如Perl、Ruby、Python、Java、C、Fortran或Cobol。 欢迎使用awk、sed或sort等标准Unix工具。 所有概率必须相对于文件中的最高概率。 单词是唯一的,数字不是。 计数是自然数。
谢谢大家!

这不是防错的,但类似的方法应该可以:

#!/bin/bash

INPUT=data.cvs
OUTPUT=tally.cvs
DIGITS=1

OLDIFS=$IFS
IFS=,

maxval=0  # Assuming all $val are positive

while read name val
do
    if (( val > maxval )); then maxval=$val; fi
done < $INPUT

# Make sure $OUTPUT doesn't exist

touch $OUTPUT

while read name val
do
    tally=`echo "scale=$DIGITS; result=$val/$maxval; if (0 <= result && result < 1) { print "0" }; print result" | bc`
    echo "$name,$tally" >> $OUTPUT
done < $INPUT

IFS=$OLDIFS

这不是防错的,但类似的东西应该可以工作:

#!/bin/bash

INPUT=data.cvs
OUTPUT=tally.cvs
DIGITS=1

OLDIFS=$IFS
IFS=,

maxval=0  # Assuming all $val are positive

while read name val
do
    if (( val > maxval )); then maxval=$val; fi
done < $INPUT

# Make sure $OUTPUT doesn't exist

touch $OUTPUT

while read name val
do
    tally=`echo "scale=$DIGITS; result=$val/$maxval; if (0 <= result && result < 1) { print "0" }; print result" | bc`
    echo "$name,$tally" >> $OUTPUT
done < $INPUT

IFS=$OLDIFS
awk 'BEGIN{max=0;OFS=FS=","}  $NF>max{max=$NF}NR>FNR {print $1,($2/max) }' file file

从中借用,以及各种谷歌搜索。

无需将文件读取两次:

awk 'BEGIN{max=0;OFS=FS=","}  $NF>max{max=$NF}NR>FNR {print $1,($2/max) }' file file
awk 'BEGIN {OFS = FS = ","} {a[$1] = $2} $2 > max {max=$2} END {for (w in a) print w, a[w]/max}' inputfile
如果需要按单词排序的输出:

awk ... | sort


无需读取文件两次:

awk 'BEGIN {OFS = FS = ","} {a[$1] = $2} $2 > max {max=$2} END {for (w in a) print w, a[w]/max}' inputfile
如果需要按单词排序的输出:

awk ... | sort


这是一个很好的答案,也是在bash中读取CSV文件的一个很好的示例。不过,纯awk解决方案可能更有效。谢谢。@Dave:这是kurumiAn的绝妙答案,也是在bash中读取CSV文件的好例子。不过,纯awk解决方案可能更有效。谢谢。@Dave:kurumiNot读取两次文件绝对是一种有效的方法。如果你想格式化数字,你可以用{printf%s,%.3f\n,w,a[w]/max}替换{printf w,a[w]/max}来保持3个尾随数字不读取两次文件绝对是一种有效的方法。如果你想格式化数字,您可以将{print w,a[w]/max}替换为{printf%s,%.3f\n,w,a[w]/max}以保持3的尾随性digits@Marshall:bc不是bashcalc,它是台式计算器,而dc是台式计算器。@Dennis:谢谢你,为这个错误道歉confusion@Marshall:bc不是bashcalc,它是台式计算器,而dc是台式计算器。@Dennis:谢谢,很抱歉造成混淆