linux - 不使用 awk 编写 bash 脚本?

标签 linux bash shell unix awk

我们被要求编写一个shell 脚本,它将玩家记录的输入作为标准输入。

示例输入:

id|name|time
23|Jordan|45:17
14|Jason|4:50
12|Bryan|
24|Cody|00:12
33|kobe|41
55|rocky|0

并且我们需要读取我们脚本中的每个记录(跳过标题),然后输出每个相应的通过转换以秒为单位的时间并将分隔符'|'更改为''记录>(空格)。

正如我们在上面的示例测试用例中看到的,一些记录有空时间字段(第三条记录),对于那些记录以秒为单位的时间将被视为0

示例案例输出:

23 Jordan 2717
14 Jason 290
12 Bryan 0
24 Cody 12
33 kobe 2460
55 rocky 0

my_solution_script.sh

#!/bin/bash


read -r header
while IFS="|" read -r pid pname time || [[ -n $pid ]]
do  
    min=$(cut -d ':' -f 1 <<< "$time")
    sec=$(cut -d ':' -f 2 <<< "$time")
    ((min*=60))
    ((min+=sec))
    
    echo "$pid $pname $min"
done

错误的输出:

23 Jordan 2717
14 Jason 290
12 Bryan 0
24 Cody 12
33 kobe 2501
55 rocky 0

如我们所见,上面的脚本为第 5 条记录提供了错误的输出

How can I fix the above script, to get the correct output in every case?

我认为使用 awk 可能有更简单的解决方案,但我现在对“awk 脚本” 不太了解, 所以我正在寻找一种使用基本 shell 命令 来解决这个问题的方法,不过也欢迎使用 awk 命令 解决方案。

谢谢。

最佳答案

问题是 cut -d: -f2 <<< "$time"返回所有 $time当它不包含 : 时定界符。所以对于科比,你正在计算 41*60+41而不仅仅是 41*60 .

所以你需要检查是否$time包含 :在尝试获取秒数之前。

read -r header
while IFS="|" read -r pid pname time || [[ -n $pid ]]
do  
    min=$(cut -d ':' -f 1 <<< "$time")
    if [[ $time =~ : ]]
        sec=$(cut -d ':' -f 2 <<< "$time")
    else
        sec=0
    fi
    ((min*=60))
    ((min+=sec))
    
    echo "$pid $pname $min"
done

关于linux - 不使用 awk 编写 bash 脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63693884/

相关文章:

linux - 无法进行 LibreOffice 在线构建

linux - TCP:通过断开的连接提高可靠性

linux - OS如何让被中断的进程一直运行在指定的CPU上?

linux - 如何按列对一组数据进行排序?

function - 在系统中注册自定义 shell 函数 (OSX)

linux - 在特定时间用 bash 截屏

我可以使用 AC_XXXX_CONFIG 语法将我的宏定义放到 config.h 中吗?

linux - 创建 aspell 样式文件编辑 bash 脚本

linux - Raspbian:从 .sh 文件启动程序

shell - 如何在 shell 函数中获得 "set -e"的效果和用处?