Linux下编写letter.sh脚本提取Word文档文本遇阻求助
解决Word文档XML中
<w:t>标签文本提取问题 看起来你在提取Word文档XML里的文本时遇到了grep使用的问题,我来帮你分析下问题所在并给出几个可行的解决方案:
首先,咱们先拆解你当前命令的几个明显问题:
- 正则表达式逻辑错误:你用的
"<w:t>*</w:t>"里的*是正则量词(匹配前面字符0次或多次),不是用来匹配任意文本的通配符,这样根本抓不到标签内的内容。 - 重定向方向搞反:
< touch letter.txt是把letter.txt作为输入传给grep,这完全不符合你要输出文本到文件的需求,应该用>来将结果写入文件。 - 单行匹配限制:grep默认只处理单行文本,如果
<w:t>和</w:t>不在同一行,就会匹配失败。
下面给你几个实用的解决方向:
方法1:改进grep命令(适合单行文本场景)
如果你的<w:t>标签和内容都在同一行,可以用扩展正则配合sed提取纯文本:
# 提取所有<w:t>标签内的内容,剥离标签后写入letter.txt grep -oE "<w:t>([^<]+)</w:t>" ~word/document.xml | sed 's/<w:t>\(.*\)<\/w:t>/\1/' > letter.txt
-o:只输出匹配到的部分-E:启用扩展正则表达式,让语法更直观[^<]+:匹配<w:t>和</w:t>之间的非<字符(避免误匹配嵌套标签,Word的<w:t>一般不会嵌套)sed命令用来剥离XML标签,只保留纯文本
方法2:用sed处理跨行文本场景
如果<w:t>和</w:t>可能分布在多行,sed的多行处理能力更合适:
# 匹配从<w:t>到</w:t>的内容块,剥离标签后输出(可选择是否合并换行) sed -n '/<w:t>/,/<\/w:t>/ { s/<w:t>//g; s/<\/w:t>//g; p }' ~word/document.xml > letter.txt # 如果需要把跨行内容合并为单行,加上tr命令: # sed -n '/<w:t>/,/<\/w:t>/ { s/<w:t>//g; s/<\/w:t>//g; p }' ~word/document.xml | tr -d '\n' > letter.txt
/<w:t>/,/<\/w:t>/:匹配从<w:t>开始到</w:t>结束的所有行s/<w:t>//g和s/<\/w:t>//g:全局替换掉标签tr -d '\n':可选操作,用来去掉换行符,将所有文本合并为一行
方法3:用专业XML工具(推荐,最可靠)
正则处理XML本质上是“权宜之计”,因为XML的结构可能有嵌套、换行、命名空间变化等情况,专业工具能更稳定地解析。比如xmlstarlet:
# 提取所有<w:t>节点的文本内容,每个内容占一行 xmlstarlet sel -t -v "//w:t" -n ~word/document.xml > letter.txt
- 如果你的系统没有
xmlstarlet,可以安装:- Debian/Ubuntu:
sudo apt install xmlstarlet - macOS(Homebrew):
brew install xmlstarlet
- Debian/Ubuntu:
- 这个命令会自动处理XML的命名空间、跨行、嵌套等问题,是最稳妥的方案。
内容的提问来源于stack exchange,提问作者robe320




