我想要一个循环,可以找到以多种语言最频繁地结束单词并以列形式输出数据的字母。 到目前为止我已经
了count="./wordlist/french/fr.txt ./wordlist/spanish/es.txt ./wordlist/german/de.$
lang="French Spanish German Portuguese Italian"
(
echo -e "Language Letter Count"
for i in $count
do
(for j in {a..z}
do
echo -e "LANG" $j $(grep -c $j\> $i)
done
) | sort -k3 -rn | head -1
done
) | column -t
我希望它输出如下所示:
Language Letter Count
French e 196195
Spanish a 357193
German e 251892
Portuguese a 217178
Italian a 216125
相反,我得到:
Language Letter Count
LANG z 0
LANG z 0
LANG z 0
LANG z 0
LANG z 0
单词文件的格式为:
Word Freq(#)
其中单词及其频率由空格分隔。
这意味着我有两个问题;
首先,grep
命令不处理参数$j\>
以在单词的末尾查找字符。我尝试过使用grep -E $j\>
和grep '$j\>'
,但都没有效果。
第二个问题是我不知道如何输出语言的名称(在变量lang
中)。当我像这样尝试(或者以相反的顺序使用i和k)时,嵌套另一个for
循环不起作用:
(
for i in $count
do
for k in $lang
do
for j in {a..z}
do
echo -e $k $j $(grep -c $j\> $i)
done
) | sort -k3 -rn | head -1
done
done
) | column -t
因为这会在不属于的地方输出语言“$k
”的倍数。
我知道我可以复制并粘贴每种语言的循环,但我想将其扩展到每种语言。 提前谢谢!
答案 0 :(得分:2)
grep
字边界要从shell中调用特殊分隔符(例如,word {end \>
)与egrep
一起使用,您应该将它们放入"
引号"
。
count=$(egrep -c "${char}\>" "${file}")
顺便说一句,你真的应该使用双引号("
),因为单引号会阻止变量扩展。 (例如,在j="foo"; k='$j\>'
中,k
的第一个字符值为$
而不是f
)
获得正确的语言字符串有点棘手;这里有一些建议:
从词汇表的路径中导出显示的语言:
lang=${file%/*}
lang=${lang##*/}
使用bash(虽然没有破折号和其他一些shell),你甚至可以lang=${lang^}
来大写字符串。
在字典中查找正确的语言名称。 Bash-4
内置了词典,但您也可以使用基于文件的词典:
$ cat languagues.txt
./wordlist/french/fr.txt Français
./wordlist/english/en.txt English
./wordlist/german/de.txt Deutsch
$ file=./wordlist/french/fr.txt
$ lang=$(egrep "^${file}/>" languages.txt | awk '{print $2}')
您还可以迭代file,lang
对,例如
languages="french/fr,French spanish/es,Español german/de,Deutsch"
for l in $languages; do
file=./wordlist/${l%,*}.txt
lang=${l#*,}
# ...
done
我看到的第三个问题(虽然我可能误解了这个问题),是你没有考虑频率这个词。例如单词 A 使用频率比单词 B 高1000倍只会被计算一次(就像 B 一样)。
您可以使用awk
来总结匹配单词的单词频率:
count=$(egrep "${char}\>" "${file}" | awk '{s+=$2} END {print s}')
因此问题的完整解决方案可能如下:
languages="french/fr,French spanish/es,Español german/de,Deutsch"
(
echo -e "Language Letter Count"
for l in ${languages}; do
file=./wordlist/${l%,*}.txt
lang=${l#*,}
for char in {a..z}; do
#count=$(egrep -c "${char}\>" "${file}")
count=$(egrep "${char}\>" "${file}" | awk '{s+=$2} END {print s}')
echo ${file} ${char} ${count}
done | sort -k3 -rn | head -1
done
) | column -t