【问题标题】:Bourne shell: reading multiple lines of stdinBourne shell:读取多行标准输入
【发布时间】:2015-03-24 14:43:50
【问题描述】:

我是 Bourne shell 的新手,对阅读多行/包括换行符的标准输入感到好奇。

IN:例如,如果有人输入

1
  3         #only ignore whitespace
5.3         #ignore floating point number all together

我可以让它读取它们并在不同的行中回显它们。我的目标也是忽略浮点数(仅限整数!)并忽略空格

OUT:我的理想输出将计算平均值(上面输入的示例)

1
2

到目前为止,我可以读取标准输入并将其回显,如果它在一行上并且限制为硬编码值(应该是每当用户使用 Ctrl-D 停止时)。

#! /bin/sh

read a b c

echo "$a";
echo "$b";
echo "$c";

【问题讨论】:

  • 它是针对你使用 sh 卡住的作业吗?因为 bash 是 sh 的超集,并且有一些非常方便的字符串操作符和更好的读取功能。我认识的大多数公司/工程师不久前都切换到 bash 来编写 UNIX 上的大部分基本 shell 脚本。它是 Linux 登录的默认 shell。甚至是 Solaris。
  • @1sand0s 是的,这次别无选择了!我更喜欢使用 bash,虽然我不喜欢它,但我更喜欢 tcsh。

标签: shell integer sh stdin


【解决方案1】:

已经有一段时间了,但以下应该只为整数输入获得sumaverage

#!/bin/sh

sum=0;
cnt=0

while read line
do

    case "$line" in

        *[.]*  )
            continue
            ;;

        [0-9]* ) 
            sum=`expr "$sum" + "$line"`
            cnt=`expr "$cnt" + 1`
            ;;
    esac

done

printf "\nThe sum is '%s', cnt is '%s' the average is '%s'\n\n", "$sum" "$cnt" `expr $sum / $cnt`

输出

$ printf "1\n 3\n5.3\n" | sh bourne_sum.sh

The sum is '4', cnt is '2' the average is '2'

在文件中输入

$ cat dat/bsum.txt
1
 3
5.3

简单的重定向就可以了:

$ sh bourne_sum.sh <dat/bsum.txt

The sum is '4', cnt is '2' the average is '2'

修改为 1 行输出

#!/bin/sh

sum=0;
cnt=0

while read line
do

    case "$line" in

        *[.]*  )
            printf " 0"
            continue
            ;;

        [0-9]* ) 
            sum=`expr "$sum" + "$line"`
            cnt=`expr "$cnt" + 1`
            printf " %s" `expr $sum / $cnt`
            ;;
    esac

done

printf "\n"

# printf "\nThe sum is '%s', cnt is '%s' the average is '%s'\n\n" "$sum" "$cnt" `expr $sum / $cnt`

输出

$ printf "1\n3\n5\n4.4\n" | sh bourne_sum.sh
 1 2 3 0

仅响应整数

#!/bin/sh

sum=0;
cnt=0

while read line
do

    if [ $line -eq $line 2>/dev/null ]
    then

        sum=`expr "$sum" + "$line"`
        cnt=`expr "$cnt" + 1`
        printf " %s" `expr $sum / $cnt`

    fi

done

printf "\n"

输出

$ printf "1\n3\n5\n4.4\n'2 3'\n" | sh bourne_sum.sh

 1 2 3

【讨论】:

  • 虽然这可以正确读取它,但它不会让我按需要打印出来。我如何从它的读取方式中提取,如果输入是新行的每个数字:1 3 5 4.4。它会输出 1 2 3 0 因为忽略 4.4(不是 int)
  • 见补充回答。这取决于你想要什么。您需要做的就是移动printf 语句以产生所需的输出。如果您有更多问题,请告诉我。 (哦等等,我看到你仍然想要平均值和持续总和.. 等等..(固定)
  • 是的,我怎样才能让它忽略它不仅仅是一个整数的情况?我希望它在一行上完全忽略“5 6”之类的东西(每行只允许一个整数或“5 hello text”,只是为了跳过那些/让它像浮点数一样输出0。
  • 您可以添加一个测试[ $var -eq $var ],该测试仅在$varint 时成功,并且在所有其他情况下都将失败。您可能希望将输出重定向到stderr。例如if [ $var -eq $var 2&gt;/dev/null ]; then printf "%d is an int\n" $var; else printf "%d is NOT an int\n" $var; fi
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-09
  • 2017-09-07
  • 1970-01-01
  • 2011-06-02
相关资源
最近更新 更多