Bash 如何在for循环中递增字符串变量

Bash 如何在for循环中递增字符串变量,bash,for-loop,grep,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}

我想要一个循环,可以找到在多种语言中最常以单词结尾的字母,并在列中输出数据。 到目前为止我有

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
我希望它输出如下所示:

因为这会在语言不属于的地方输出语言名称的倍数“
$k

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

grep
单词边界 当从shell调用时,要使特殊分隔符(例如,单词结尾的
\>
egrep
一起使用,您应该将它们放入
引号

顺便说一句,您确实应该使用双引号(
),因为单引号将阻止变量扩展。(例如,在
j=“foo”;k='$j\>'
中,
k
值的第一个字符将是
$
,而不是
f

语言名称显示 获取正确的语言字符串有点棘手;以下是一些建议:

  • 从单词列表的路径派生显示的语言:

    lang=${file%/*}
    lang=${lang##*/}
    
    使用bash(尽管不使用dash和其他一些shell),您甚至可以执行
    lang=${lang^}
    来将字符串大写

  • 在字典中查找正确的语言名称。
    Bash-4
    内置了字典,但也可以使用基于文件的dict:

    $ 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}')
    
  • 您还可以迭代
    文件、lang
    对,例如

    languages="french/fr,French spanish/es,Español german/de,Deutsch"
    for l in $languages; do
       file=./wordlist/${l%,*}.txt
       lang=${l#*,}
       # ...
    done
    
考虑词频 我看到的第三个问题(尽管我可能误解了这个问题),是你没有考虑单词的频率。例如,一个比单词B多1000倍的单词a只会被计算一次(就像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
grep
单词边界 当从shell调用时,要使特殊分隔符(例如,单词结尾的
\>
egrep
一起使用,您应该将它们放入
引号

顺便说一句,您确实应该使用双引号(
),因为单引号将阻止变量扩展。(例如,在
j=“foo”;k='$j\>'
中,
k
值的第一个字符将是
$
,而不是
f

语言名称显示 获取正确的语言字符串有点棘手;以下是一些建议:

  • 从单词列表的路径派生显示的语言:

    lang=${file%/*}
    lang=${lang##*/}
    
    使用bash(尽管不使用dash和其他一些shell),您甚至可以执行
    lang=${lang^}
    来将字符串大写

  • 在字典中查找正确的语言名称
    Bash-4
    内置了字典,但您也可以使用基于文件的dict:

    $ 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}')
    
  • 您还可以迭代
    文件、lang
    对,例如

    languages="french/fr,French spanish/es,Español german/de,Deutsch"
    for l in $languages; do
       file=./wordlist/${l%,*}.txt
       lang=${l#*,}
       # ...
    done
    
考虑词频 我看到的第三个问题(尽管我可能误解了这个问题),是你没有考虑单词频率。e、 一个比B多使用1000倍的单词a只会被计算一次(就像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

你能从两个单词列表文件中粘贴几行来进行测试吗?即使这样做有效,它不会输出错误的数字吗?e、 g.如果您的字数文件有三个条目:
为1000;xertz 1;娱乐圈1结果将是
z2
(而不是
s1000
)是的,Umlaute,它将
z2
,这是我想要的,因为我想计算频率并显示文件本身中最常以单词结尾的字符。roelofs,这里显示了该文件的一个示例:
de 1622928 je 1622619 est 1348809 pas 1128894 le 1093232
因此在该文件本身中,e通常以单词结尾。对不起,这是一个误解。你能从两个单词列表文件中粘贴几行来进行测试吗?即使这样做有效,它不会输出错误的数字吗?e、 g.如果您的字数文件有三个条目:
为1000;xertz 1;娱乐圈1结果将是
z2
(而不是
s1000
)是的,Umlaute,它将
z2
,这是我想要的,因为我想计算频率并显示文件本身中最常以单词结尾的字符。roelofs,这里显示了该文件的一个示例:
de 1622928 je 1622619 est 1348809 pas 1128894 le 1093232
因此在该文件本身中,e通常以单词结尾。很抱歉误解了。这非常有效,我学到了一些新东西,谢谢乌姆劳特!如果你不介意的话,我确实有个问题,你能告诉我你是如何使用
${l%,*}
${l#*,}
?我仍然对脚本中
%
#
的用法感到困惑,它们到底是什么意思?@Angelo
man bash
和搜索
#
应该会给你一个比我能说的更好的解释。这非常有效,我学到了一些新东西,谢谢乌姆劳特!如果你不介意的话,我确实有个问题,你能告诉我你是如何使用
${l%,*}
${l#*,}
?我仍然对脚本中
%
#
的用法感到困惑,它们到底是什么意思?@Angelo
man bash
和search for
#
应该给你一个比我能说的更好的解释。