从文件中读取数字并在 IF 语句中进行比较

read numbers from files and compare them in an if statement

提问人:Doom 提问时间:11/11/2023 最后编辑:BarmarDoom 更新时间:11/11/2023 访问量:58

问:

#!/bin/bash

nomFich="fichier.txt"

n=$(sort $nomFich | uniq | wc -l)

while read nom; do
    read pren
    read score
     if [[ $score -gt 50 ]]; then
        echo $nom
        echo $pren
        echo $score  
    fi
    
done < "StudentThatCompletedtheExam.txt"

我正在阅读该文件 nomFich 中的行 结构如下:

mohamed
ali
90
ali
salem
95
paul
bens
46

我想一次读取 3 行,这样我就可以存储所有变量,然后如果名为 score 的第 3 个变量大于 50,我将所有 3 个变量放入另一个文件。

问题是,如果语句不起作用,则无法比较,控制台输出为:$score50

$ ./test.sh 
")syntax error: invalid arithmetic operator (error token is "
")syntax error: invalid arithmetic operator (error token is "
")syntax error: invalid arithmetic operator (error token is "

我尝试将$score转换为 int,但它不起作用 我尝试了其他一切。 我想这样做,因为初学者很容易理解它。

Linux bash UNIX

评论

2赞 Barmar 11/11/2023
我认为您的文件有 CRLF 换行符。用 修复它。dos2unix
1赞 Barmar 11/11/2023
该脚本从不使用 .$n
2赞 Gordon Davisson 11/11/2023
请参阅“shell 脚本对编码和行尾敏感吗?”,了解处理 CRLF 格式文件的信息和选项。使用可能是这里最好的选择(请参阅我对这个问题的回答)。IFS=$'\r' read ...
0赞 Doom 11/11/2023
@Barmar 它的工作原理是,它输出了三次错误,这是预期的,以及如何用dos2unix修复它
2赞 markp-fuso 11/11/2023
@Doom每行的尾随表示从文件中读取的每个值的末尾都有一个 (CR)。对于变量,条件如下所示: 这反过来又会产生错误,指出 ;消除错误,错误就消失了\r\rscore[[ 90\r -gt 50 ]]bash[[ 90 \r -gt 50 ]]\r is an invalid arithmetic operator\r

答:

0赞 Luke Attard 11/11/2023 #1

跑:

vim StudentThatCompletedtheExam.txt -c "set ff=unix" -c ":wq"
vim fichier.txt -c "set ff=unix" -c ":wq"

我认为只有文件StudentThatCompletedtheExam.txt有问题,但我包含了这两个文件以防万一。

这将解决 eol 被格式化的问题,然后脚本应该可以正常工作。我已经在我的系统上对其进行了测试,并且能够复制该问题,并且修复有效。

0赞 dawg 11/11/2023 #2

使用比 Bash 更好的工具可能更容易做到这一点。

这是一个awk:

awk 'FNR%3==1{split("",rec)}
{rec[FNR%3]=$1}
FNR%3==0 && $1>50{print rec[1] ORS rec[2] ORS $1}' file

或者是红宝石:

ruby -e '$<.read.split(/\R/).
            each_slice(3){|first,last,score| 
                puts "#{first}\n#{last}\n#{score}" if score.to_i>50} ' file

任一打印:

mohamed
ali
90
ali
salem
95

如果您有 DOS 行尾,您可以设置输入记录分隔符以过滤掉如下所示的内容:\r

awk -v FS="\r?\n" 'FNR%3==1{split("",rec)}
{rec[FNR%3]=$1}
FNR%3==0 && $1>50{print rec[1] ORS rec[2] ORS $1}' file

Ruby 已经处理了 DOS 或 Unix 行尾,因为拆分是通用的。\R