数字を完全な書面テキストに変換

数字を完全な書面テキストに変換

数値を完全なテキストに変換するスクリプトをLinuxで作成する必要があります。時間が触れて例外もなく、カンマの後の数字もないコードを解くべきだったけどそれでもダメですね。プログラムは変数を認識しないので、主に構文に関連する助けが必要です。これが私が今持っているものです(オランダ語で)。

更新:(私の考えでは)最も重要な部分を英語に翻訳しました。

#!/bin/bash
echo -prijs "Give the price: "
read price

thousands='expr $price /1000'
hundreds='expr ($price - $thousands) / 100'
teens='expr ($price - $hundreds - $thousands / 10'
units='expr $price - $hundreds - $thousands - $teens'

    for ((i=0 ; i<=$thousands; i++ ))
do
    case $thousands in
        0) echo -prijs "";;
        1) echo -prijs "duizend";;
        2) echo -prijs "tweeduizend";;
        3) echo -prijs "drieduizend";;
        4) echo -prijs "vierduizend";;
        5) echo -prijs "vijfduizend";;
        6) echo -prijs "zesduizend";;
        7) echo -prijs "zevenduizend";;
        8) echo -prijs "achtduizend";;
        9) echo -prijs "negenduizend";;
        10) echo -prijs "tienduizend";;
    esac
done
    for ((i=0 ; i<=$hundreds; i++ ))
do
    case $hundreds in
        0) echo -prijs "";;
        1) echo -prijs "honderd";;
        2) echo -prijs "tweehonderd";;
        3) echo -prijs "driehonderd";;
        4) echo -prijs "vierhonderd";;
        5) echo -prijs "vijfhonderd";;
        6) echo -prijs "zeshonderd";;
        7) echo -prijs "zevenhonderd";;
        8) echo -prijs "achthonderd";;
        9) echo -prijs "negenhonderd";;
    esac
done
    for ((i=0 ; i<=$teens; i++ ))
do
    case $teens in
        0) echo -prijs "";;
        1) echo -prijs "tien";;
        2) echo -prijs "twintig";;
        3) echo -prijs "dertig";;
        4) echo -prijs "veertig";;
        5) echo -prijs "vijftig";;
        6) echo -prijs "zestig";;
        7) echo -prijs "zeventig";;
        8) echo -prijs "tachtig";;
        9) echo -prijs "negentig";;
    esac
done
    for ((i=0 ; i<=$units; i++ ))
do
    case $units in
        0) echo -prijs "";;
        1) echo -prijs "een";;
        2) echo -prijs "twee";;
        3) echo -prijs "drie";;
        4) echo -prijs "vier";;
        5) echo -prijs "vijf";;
        6) echo -prijs "zes";;
        7) echo -prijs "zeven";;
        8) echo -prijs "acht";;
        9) echo -prijs "negen";;
    esac
done

echo "The price is: " 'expr $thousands + $hundreds + $teens + $units'

答え1

コードにはいくつかの問題があります。最初の問題は、バックティックを使用する必要がある場所に一重引用符を使用していることです。 2番目の問題は、exprbashでは実際には必要ありませんが、$(())これを行うことです。 3番目の問題は、公式が単に間違っているということです。 4番目の問題は-prijsコメントで指摘されています。コードのこの部分を書き直してください。

thousands='expr $price /1000'
hundreds='expr ($price - $thousands) / 100'
teens='expr ($price - $hundreds - $thousands / 10'
units='expr $price - $hundreds - $thousands - $teens'

到着

thousands=$((price/1000))
hundreds=$((price%1000/100))
teens=$((price%100/10))
units=$((price%10))

%Bashのモジュロ演算子はどこにありますか?-prijs残りの部分(スクリプトの内容や最後の行など)を直接修正してみてください。

答え2

興味深い挑戦です。これは私の意見です

#!/bin/bash

digits=(
    "" one two three four five six seven eight nine
    ten eleven twelve thirteen fourteen fifteen sixteen seventeen eightteen nineteen
)
tens=("" "" twenty thirty forty fifty sixty seventy eighty ninety)
units=("" thousand million billion trillion)

number2words() {
    local -i number=$((10#$1))
    local -i u=0
    local words=()
    local group

    while ((number > 0)); do
        group=$(hundreds2words $((number % 1000)) )
        [[ -n "$group" ]] && group="$group ${units[u]}"

        words=("$group" "${words[@]}")

        ((u++))
        ((number = number / 1000))
    done
    echo "${words[*]}"
}

hundreds2words() {
    local -i num=$((10#$1))
    if ((num < 20)); then
        echo "${digits[num]}"
    elif ((num < 100)); then
        echo "${tens[num / 10]} ${digits[num % 10]}"
    else
        echo "${digits[num / 100]} hundred $("$FUNCNAME" $((num % 100)) )"
    fi
}

with_commas() {
    # sed -r ':a;s/^([0-9]+)([0-9]{3})/\1,\2/;ta' <<<"$1"
    # or, with just bash
    while [[ $1 =~ ^([0-9]+)([0-9]{3})(.*) ]]; do
        set -- "${BASH_REMATCH[1]},${BASH_REMATCH[2]}${BASH_REMATCH[3]}"
    done
    echo "$1"
}

for arg; do
    [[ $arg == *[^0-9]* ]] && result="NaN" || result=$(number2words "$arg")
    printf "%s\t%s\n" "$(with_commas "$arg")" "$result"
done

実行中:

$ bash ./num2text.sh 9 98 987 9786 98765 987654 9876543 98765432 987654321 9876543210 98765432100 987654321000 9876543210000 98765432100000 987654321000000 1,234 x 1y z2
9       nine
98      ninety eight
987     nine hundred eighty seven
9,786   nine thousand seven hundred eighty six
98,765  ninety eight thousand seven hundred sixty five
987,654 nine hundred eighty seven thousand six hundred fifty four
9,876,543       nine million eight hundred seventy six thousand five hundred forty three
98,765,432      ninety eight million seven hundred sixty five thousand four hundred thirty two
987,654,321     nine hundred eighty seven million six hundred fifty four thousand three hundred twenty one
9,876,543,210   nine billion eight hundred seventy six million five hundred forty three thousand two hundred ten
98,765,432,100  ninety eight billion seven hundred sixty five million four hundred thirty two thousand one hundred
987,654,321,000 nine hundred eighty seven billion six hundred fifty four million three hundred twenty one thousand
9,876,543,210,000       nine trillion eight hundred seventy six billion five hundred forty three million two hundred ten thousand
98,765,432,100,000      ninety eight trillion seven hundred sixty five billion four hundred thirty two million one hundred  thousand
987,654,321,000,000     nine hundred eighty seven trillion six hundred fifty four billion three hundred twenty one million
1,234   NaN
x       NaN
1y      NaN
z2      NaN

答え3

未来の私とこの命令を探しているすべての人のために。


タブリストをスクロール中に、偶然に次のコマンドが見つかりました。

spellout 1.0.11: convert numbers to number names and money amounts
Usage: spellout [-l lang] [-p prefix] par1 [par2...]
Parameter: n: number; n-m: range; n-m~s: range with step
Examples: spellout 1-10 500 1000-10000~1000
          spellout -l en-GB -p ordinal 1-100
          spellout -l en -p ordinal-number 1-100
          spellout -l en -p USD 100.45
          spellout -l en -p "money USD" 100.45
Help of language module: spellout -l es help
License: GNU LGPL/BSD dual-license

私はそれが(おそらく)次に由来したことがわかりました。番号テキスト/lib番号テキストとすることができますDebian ソースコード


例:

$ spellout 39825
thirty-nine thousand eight hundred twenty-five
$ spellout -l de-DE 39825
neununddreißigtausendachthundertfünfundzwanzig
$ spellout -l en-US -p "money GBP" 39825
thirty-nine thousand eight hundred twenty-five pounds sterling
$ spellout  -l de-DE -p ordinal 39825
neununddreißigtausendachthundertfünfundzwanzigste

関連情報