Bash脚本统计交易日志股票交易数异常:IBM计数少1
问题:股票交易日志计数错误排查与修复
需求说明
- 统计交易日志中各股票Symbol的交易次数,按交易次数降序排列,每行对应一笔交易。
- 输入日志每行格式:
Datetime(YYYYMMDDHHMMSS), Stock, Symbol, BUY/SELL, Quantity, Price
输入输出示例
示例输入
Datetime(YYYYMMDDHHMMSS), Stock, Symbol, BUY/SELL, Quantity, Price 20190102091055,IBM,BUY,1.160 20190102091058,BABA,SELL,10,155 20190102091059,IBM,BUY,2,159
预期输出
IBM 2 BABA 1
现有脚本
#!/bin/bash declare -A symbols # Declare an associative array to store the symbols and their counts # Read input line by line while read line do # Extract the stock symbol from the line symbol=$(echo "$line" | cut -d',' -f2) # If the symbol already exists in the array, increment its count # Otherwise, add the symbol to the array with a count of 1 if [[ ${symbols[$symbol]+_} ]]; then symbols[$symbol]=$((symbols[$symbol]+1)) else symbols[$symbol]=1 fi done < "${1:-/dev/stdin}" # Read input from stdin or from a file specified as a command-line argument # Sort the symbols and their counts in descending order of count for symbol in "${!symbols[@]}" do echo "$symbol ${symbols[$symbol]}" done | sort -rnk2
问题现象
测试输入中IBM预期交易次数为27,但脚本输出为26,其余股票计数正确。
测试输入(截断版)
20190527200918,AMZN,SELL,32,1830 20190527200918,AMZN,BUY,26,1827 20190527200918,IBM,SELL,12,139 20190527200918,IBM,SELL,93,144 20190527200918,IBM,SELL,6,141 20190527200918,AMZN,BUY,44,1833 20190527200918,GOOG,SELL,77,1145 20190527200918,GOOG,BUY,89,1135 20190527200918,IBM,BUY,21,139 20190527200918,AMZN,BUY,89,1834 20190527200918,IBM,SELL,80,139 20190527200918,MSFT,SELL,48,135 20190527200918,MSFT,BUY,66,131 20190527200918,MSFT,SELL,21,141 20190527200918,AMZN,SELL,5,1826 20190527200918,MSFT,BUY,47,141 20190527200918,AMZN,SELL,19,1833 20190527200918,AMZN,BUY,22,1831 20190527200918,IBM,BUY,75,139 20190527200918,GOOG,BUY,70,1141 20190527200918,AAPL,SELL,43,182 20190527200918,MSFT,BUY,7,136 20190527200918,GOOG,SELL,89,1147 20190527200918,AMZN,SELL,54,1828 20190527200918,AAPL,SELL,7,189 20190527200918,MSFT,SELL,66,136 20190527200918,AAPL,SELL,31,189 20190527200918,IBM,BUY,39,137 20190527200918,MSFT,SELL,10,128 20190527200918,IBM,BUY,15,146 20190527200918,IBM,SELL,38,133 20190527200918,IBM,SELL,76,146 20190527200918,G{-truncated-}
脚本输出
IBM 26 MSFT 22 AMZN 21 GOOG 17 AAPL 13
预期输出
IBM 27 MSFT 22 AMZN 21 GOOG 17 AAPL 13
问题排查与修复
问题根源
原脚本使用while read line读取输入时,若文件最后一行没有换行符,read会返回非零状态码,导致该行被跳过不处理。测试输入的最后一行恰好是截断行且无换行符,这正是IBM计数少1的原因。此外,原脚本的计数逻辑可以简化,还可添加表头跳过、空Symbol过滤的逻辑增强鲁棒性。
修复后的脚本
#!/bin/bash declare -A symbols # 读取所有行,包括无换行符的最后一行 while IFS= read -r line || [ -n "$line" ]; do # 跳过表头行(如果输入包含表头) if [[ "$line" == Datetime* ]]; then continue fi # 提取第二个字段作为Symbol symbol=$(echo "$line" | cut -d',' -f2) # 仅对非空Symbol计数 if [[ -n "$symbol" ]]; then ((symbols[$symbol]++)) fi done < "${1:-/dev/stdin}" # 按交易次数降序输出 for symbol in "${!symbols[@]}"; do echo "$symbol ${symbols[$symbol]}" done | sort -rnk2
关键优化点
- 处理无换行符的最后一行:
while IFS= read -r line || [ -n "$line" ]确保即使最后一行没有换行符,只要内容非空就会被处理。 - 简化计数逻辑:
((symbols[$symbol]++))无需判断Symbol是否已存在,Bash会自动将不存在的数组元素初始化为0后自增。 - 增强鲁棒性:添加表头跳过逻辑和空Symbol过滤,避免无效数据干扰统计。
内容的提问来源于stack exchange,提问作者julia lum
相关产品推荐
相关产品推荐

