Sed算法与算术

时间:2014-07-17 11:36:46

标签: bash sed

我正在编写一个程序,如果用户输入一个数字,(该数字指的是正在销售的商品数量)。然后,程序将自动更新可用数量和销售数量,并反映给用户。

我还想知道是否有办法阻止用户输入一个比int存储更大的整数" $ avilable"变量

谢谢

输出如下所示。

Title : Star Wars VI – Return of the Jedi
Author : Darth Vader
No. of copies sold  : 3
Current book  info :    
Star Wars VI – Return of the Jedi, Darth Vader, $8.05,  30, 20 

New book info :     
Star Wars VI – Return of the Jedi, Darth Vader, $8.05,  27, 23 

以下是我的代码,但由于无效,我遇到了困难。

 {
    echo -n "Title: "  
    read title
    echo -n "Author: "
    read author
    echo -n "No. of copies sold: "
    read numsold 
    if [[ ! $numsold|| $numsold = *[^0-9]* ]]; then
    echo "Please input a number." >&2
    fi
    newavilable=$((avilable - numsold)) 
    newsold=$((sold + numsold))
    sed "s/${sold}/${newsold}/g" BookDB.txt > BookDB1.txt
    mv -f BookDB1.txt BookDB.txt
    sed "s/${avilable}/${newavilable}/g" BookDB.txt > BookDB1.txt
    mv -f BookDB1.txt BookDB.txt
    echo $title:$author:$price:$avilable:$sold >> BookDB.txt
}

1 个答案:

答案 0 :(得分:1)

我会这样做:

#!/bin/bash
info=""
# while $info is not set
while [[ -z "$info" ]] ; do
    # Get at title
    title=""
    while [[ -z "$title" ]] ; do
        echo -n "Title: "
        read title
    done

    # Get an author
    author=""
    while [[ -z "$author" ]] ; do
        echo -n "Author: "
        read author
    done

    # Check book is in DB
    info=$(grep "^${title}:${author}:" BookDB.txt)
    if [[ -z "$info" ]] ; then
        echo "Not in database."
    fi
done

# Extract number of books available/already sold
avilable="$(cut -d: -f4 <<< $info)"
sold="$(cut -d: -f5 <<< $info)"

# Get number of recently sold books
while [[ -z "$numsold" ]] ; do
    # We want a number…
    while [[ ! "$numsold" =~ ^[0-9]{1,}$ ]] ; do
        echo -n "No. of copies sold: "
        read numsold
    done
    newavilable=$((avilable - numsold))
    newsold=$((sold + numsold))
    # And we want it lower than $newavilable
    if [[ $newavilable -lt 0 ]] ; then
        echo "Too high"
        numsold=""
    fi
done

# Print old info
echo "Current book info:"
echo "$info"

# Currently prints desired new DB
echo "New book info:"
# Add '-i' option to sed to edit BookDB.txt in place instead of printing it
sed -e "s/^\(${title}:${author}:[0-9]\+\):${avilable}:${sold}$/\1:${newavilable}:${newsold}/" \
    BookDB.txt

在bash测试中,不要忘记用双引号括起您的变量,否则当它们为空时会有惊喜。


修改 如果您的价格是浮点而不是整数,您可以使用以下内容提取它:

price="$(cut -d: -f3 <<< $info)"

并用

替换final sed命令
sed -e "s/^\(${title}:${author}:${price}\):${avilable}:${sold}$/\1:${newavilable}:${newsold}/" BookDB.txt
#               extracted value ^^^^^^^^

sed -e "s/^\(${title}:${author}:[0-9.]\+\):${avilable}:${sold}$/\1:${newavilable}:${newsold}/" BookDB.txt
#                       added a dot ^

由于bash不处理浮点数,请使用类似bc(或dc或perl / python / ...)的操作来执行操作,例如类似于:

totalprice=$(echo "$unitprice * $numsold" | bc)