You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash解析Fortune数据库结果与Python不符,求问题排查方案

问题

我尝试用Bash命令解析Fortune数据库文件:

$ mapfile -d '%' -t QUOTES < ~/.sigfile
$ echo ${#QUOTES}
302
$

但用Python解析同一份数据库时,得到的列表长度(我认为这个结果正确)要小得多:

>>> import re
>>> fort_arr = re.split(r"\n%\n", open("/home/matej/.sigfile").read())
>>> print(len(fort_arr))
202
>>>

请问我哪里操作有误?另外我无法安装/usr/bin/fortune,所有解析必须用纯Bash及基础Unix工具完成。我注意到Stack Overflow上有近似重复的问题,但该问题已关闭且给出的方案非常繁琐复杂。


错误原因

你用Bash的mapfile时指定的分隔符是单独的%,但Fortune数据库的条目分隔符实际是换行+%+换行(\n%\n),这和Python代码里用的分隔符完全不一致。单独按%分割会把条目内容中包含的%字符也当成分隔符,导致分割出大量无效条目,所以数组长度远大于正确值。

纯Bash解决方案

方法1:用awk分割(简洁高效)

awk原生支持多行记录分隔符,能完美匹配Fortune的格式:

# 将所有条目存入数组QUOTES
mapfile -t QUOTES < <(awk -v RS='\n%\n' '1' ~/.sigfile)
# 输出数组长度验证结果
echo ${#QUOTES[@]}

原理:通过-v RS='\n%\n'把awk的记录分隔符设置为\n%\n,1是简化的打印指令,会输出每个分割后的条目,再用mapfile将这些条目读取到数组中。

方法2:纯Bash循环读取(无外部工具依赖)

如果不想依赖awk,可以用Bash内置的read命令结合自定义分隔符:

QUOTES=()
# 以\n%\n为分隔符读取每个条目
while IFS= read -r -d $'\n%\n' quote; do
    QUOTES+=("$quote")
done < ~/.sigfile
# 处理文件末尾无分隔符的最后一个条目
[[ -n "$quote" ]] && QUOTES+=("$quote")
# 输出数组长度
echo ${#QUOTES[@]}

注意:部分旧版本Bash对多行分隔符的支持可能存在兼容性问题,优先推荐awk方案。


内容的提问来源于stack exchange,提问作者mcepl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 06:35:10