Bash 将计数转换为相对概率 出身背景
根据单词和计数的CSV文件创建概率词典。这是文本分割问题的前奏,而不是家庭作业问题 问题 给定一个CSV文件,其中包含以下文字和计数: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 问题 实
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:谢谢,很抱歉造成混淆