如何在for循环

时间:2016-10-20 00:26:29

标签: bash for-loop grep

我想要一个循环,可以找到以多种语言最频繁地结束单词并以列形式输出数据的字母。 到目前为止我已经

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”的倍数。

我知道我可以复制并粘贴每种语言的循环,但我想将其扩展到每种语言。 提前谢谢!

1 个答案:

答案 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}')

All Together Now

因此问题的完整解决方案可能如下:

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