全部版块 我的主页
论坛 计量经济学与统计论坛 五区 计量经济学与统计软件
348 0
2025-11-25

最近我在对个人日记本系统进行一次升级维护,目标是为目录页新增字数统计功能。这个系统基于Python开发,其核心流程包括:遍历当前目录下的所有txt文件,依据文件名(即日记的创建日期)排序,并按月份归类,最后结合HTML模板生成静态目录页面。

最初为了实现便捷,我在代码中大量依赖Linux shell命令来完成部分操作,例如通过shell指令获取文件列表与基本信息。

ls

初识字数统计工具:wc 命令

熟悉Linux的人大多了解 wc 指令,全称为 word count,常用于统计文本的行数、单词数和字节数。以下是来自Linux manual page的相关说明:

NAME
   wc - print newline, word, and byte counts for each
   file

SYNOPSIS
   wc [OPTION]... [FILE]...
   wc [OPTION]... --files0-from=F

DESCRIPTION
   Print newline, word, and byte counts for each FILE,
   and a total line if more than one FILE is
   specified.  A word is a nonempty sequence of non
   white space delimited by white space characters or
   by start or end of input.

   With no FILE, or when FILE is -, read standard
   input.

   The options below may be used to select which
   counts are printed, always in the following order:
   newline, word, character, byte, maximum line
   length.

在实际应用中,比如生信分析流程里,我们经常使用:

wc -l filename.txt  # 统计行数

wc -l <file>

或者:

wc -c filename.txt  # 统计字节数

wc -c <file>

以及:

wc -w filename.txt  # 统计单词数

wc -w <file>

然而这些选项并不适用于我们的需求——因为日记内容主要由UTF-8编码的中文字符构成,同时夹杂数字和英文字母。而 wc -c 统计的是总字节数,一个中文字符通常占3个字节,这会导致结果严重偏高。

wc -c

寻找正确的字符统计方式

那么,如何才能准确地统计字符数量呢?

查阅 wc 的manual page后发现,它其实支持一个关键参数:

wc

-m

-m

该参数的作用是“print the character count”,也就是统计字符个数,理论上正好符合我们的需求。

-m, --chars
    print the character counts

以北宋词人柳永的《蝶恋花》为例:

~/sd/termux $ cat test.txt
蝶恋花·伫倚危楼风细细
 柳永〔宋代〕
伫倚危楼风细细,望极春愁,黯黯生天际。草色烟光残照里, 无言谁会凭阑意。
拟把疏狂图一醉,对酒当歌,强乐还无味。衣带渐宽终不悔, 为伊消得人憔悴。
~/sd/termux $ wc test.txt
  4   4 265 test.txt
~/sd/termux $ wc -m test.txt
92 test.txt
~/sd/termux $

整首词包含标题与标点共92个字符。若直接运行 wc -c,会得到265字节的结果,显然错误;但使用 wc -m 后,输出的字符数则完全正确。

wc -m

问题再现:自动化环境中的统计偏差

正当我以为只需将 wc -m 引入Python模块即可收工时,第二天却发现服务器自动生成的统计结果依然不准确。

原因在于:这套日记系统每天通过Linux的cron服务自动扫描更新一次目录。而在crontab执行环境中,默认可能缺少完整的locale配置,导致系统使用C locale模式运行命令。在这种模式下,wc -m 实际上仍按字节处理多字节字符(如中文),从而造成误判。

经过AI提示,我了解到有两种解决方案:

  1. 在crontab中显式设置正确的locale环境变量;
  2. 改用Python内置方法进行字符统计,避免依赖外部命令和系统环境。

出于调试便利考虑,我先尝试了第一种方案。

(base) cyclin@vm:~$ LANG=C.UTF-8 wc -m test.txt
92 test.txt
(base) cyclin@vm:~$ LANG=C wc -m test.txt
265 test.txt

LANG 环境变量的影响

实验表明,在调用 wc 前设置适当的LANG值至关重要:

LANG

不同的 LANG 设置会影响 wc -m 对字符的识别能力。在本地Termux环境中多数设置都能正常工作,但在远程服务器(Ubuntu 22.04)上,只有当设定为:

LANG=en_US.UTF-8

LANG=C.UTF-8

时,wc -m 才能正确解析中文字符。

wc -m

最终推荐命令

综上所述,若希望在Linux环境下可靠地统计包含中文的文本字符数,应使用如下格式的命令:

LANG=C.UTF-8 wc -m <file>

LANG=en_US.UTF-8 wc -m filename.txt

后续优化:转向纯Python实现

在完成上述探索后,DeepSeek建议我从性能与安全角度出发,逐步淘汰对shell命令的依赖。推荐使用Python原生的文件操作接口来替代shell调用,例如:

  • os.listdir() —— 安全读取目录文件列表
    os.listdir
  • open().read() —— 直接读取内容并计算字符数
    file.read

于是我重构了相关代码。结果显示,每次扫描耗时从原来的5秒以上降至不足3秒,效率提升显著。

小结

整个过程不仅解决了字符统计的问题,也促使我对系统架构进行了更深层次的优化。此外,在统计完成后我才意识到,几年积累下来的日记竟然已突破百万字——没想到我在文字表达上如此“话痨”,不禁莞尔一笑。

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群