首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bash脚本计算器循环

Bash脚本计算器循环
EN

Unix & Linux用户
提问于 2020-09-24 09:19:44
回答 2查看 298关注 0票数 0

我有一个数据文件与一些样本数据(名字,姓氏,收入,利率)。我需要做一些计算,但是当显示结果时,我遇到了麻烦,因为它是一个循环,它没有按顺序显示。是的,我必须用bash。

示例文件:

代码语言:javascript
复制
------------------------------------
example-file.txt:

John,Rambo,99880,2%
Elon,Musk,144000,2%
------------------------------------

test.bash:

代码语言:javascript
复制
#/bin/bash

FILE=example-file.txt
 
for file in $FILE;
do
    # Get income
    INCOME=$(cat $file | awk -F, '{print $3}');
    FIRSTNAME=$(cat $file | awk -F, '{print $1}');
    LASTNAME=$(cat $file | awk -F, '{print $2}');
    # Get tax rate
    RATE=$(cat $file | awk -F, '{print $4}' | sed 's/%//');

    for foo in $INCOME
    do
     if [ "$foo" -ge 80000 ] && [ "$foo" -lt 150000 ];
        then
            for faa in $foo
            do
                NETINCOME=$(printf "%'.f\n" $(echo "(($INCOME * $RATE / 100))" | bc))
            done
    fi
    echo "${FIRSTNAME} ${LASTNAME} ${NETINCOME}"
   done
done

输出:

代码语言:javascript
复制
(standard_in) 2: syntax error
(standard_in) 3: syntax error
John
Elon Rambo
Musk 288,000
(standard_in) 2: syntax error
(standard_in) 3: syntax error
John
Elon Rambo
Musk 288,000

期望产出:

代码语言:javascript
复制
John Rambo 1997
Elon Musk 2880

我怎样才能做到这一点?

EN

回答 2

Unix & Linux用户

回答已采纳

发布于 2020-09-24 10:00:43

您的脚本有几个问题。首先,您将字符串视为数组(当for foo in $bar只是一个字符串时,没有理由或点)。第二,当您只需要读取一次文件时,您将多次读取该文件。第三,您没有引用变量,这意味着如果文件名可以包含空格,脚本就会中断。这里有一个更好的方法:

代码语言:javascript
复制
#/bin/bash

## take a list of file names as an argument so you can
## work on multiple files.
for file in "$@";
do

  ## get the values
  while read firstName lastName income  rate; do
    rate=${rate//%}
    if [[ "$income" -ge 80000  && "$income" -lt 150000 ]]; then
      netIncome=$(printf "%'.f\n" $(echo "($income * $rate) / 100" | bc))
    ## You didn't specify what should happen if the income isn't in the
    ## target range, so I am assuming you want it to be the $income unchanged.
    else
      netIncome=$income
    fi
    echo "$firstName $lastName $netIncome"
  done < <(awk -F, '{print $1,$2,$3,$4}' "$file")
done

您可以使用文件(S)作为参数来运行该文件:

代码语言:javascript
复制
$ foo.sh file
John Rambo 1,997
Elon Musk 2,880
票数 2
EN

Unix & Linux用户

发布于 2020-09-24 09:46:12

既然您使用awk从行中提取字段,那么为什么不让它来完成所有的工作呢?它应该具有足够的算术功能,将脚本转换为AWK脚本可能比修复它更容易。

代码语言:javascript
复制
$ cat example-file.txt 
John,Rambo,99880,2%
Elon,Musk,144000,2%
代码语言:javascript
复制
$ awk -v FS=, '{ print $1,$2,sprintf("%i", $3 * $4 / 100) }' example-file.txt 
John Rambo 1997
Elon Musk 2880

使用给sprintf的第一个参数来调整打印数字的格式。

你也可以过滤线路。例如,假设您只对收入范围感兴趣:

代码语言:javascript
复制
$ awk -v FS=, '
  80000 < $3 && $3 < 150000 {
    print $1,$2,sprintf("%i",$3 * $4 / 100)
  }'

它接受任意数量的文件作为参数(上限取决于您的系统配置;如果您有很多文件,请使用find ... -exec awk ...):

代码语言:javascript
复制
awk -v FS=, '...' file1.txt file2.txt ...

最后,您可以将脚本保存为一个文件,而不需要封装's,并以以下方式调用它:

代码语言:javascript
复制
awk -v FS=, -f awk_script file1.txt

消除不方便的字符串连接的需要,以防您需要在某个地方使用文字's。例如,如果希望sprintf格式字符串包含'标志,则内联脚本将变成:

代码语言:javascript
复制
awk ... '... sprintf("%'"'"'.f", $3 * $4 / 100) ...' file
票数 4
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/611119

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档