如何在Linux中使用sed将文本文件分割为不少于10个字符的块且不拆分单词?
解决sed累计字符后替换空格为|的问题
我来帮你搞定这个sed命令的问题!你的需求是每累计10个字符后找到最近的空格,把它替换成|,不过你之前写的命令在语法和逻辑上都有点问题,我来一步步拆解解决。
先说说你原命令的问题
你写的sed -E -e 's/ /|/\( *?[0-9a-zA-Z]*\)\{10,\}' new.file有几个明显的错误:
- 语法结构颠倒:sed的替换命令格式是
s/匹配规则/替换内容/,你把替换内容(/ /|/)和匹配规则(后面的正则)写反了 - 正则逻辑不对:你的正则没有贴合“累计10个字符后找最近空格”的需求,而且
*?非贪婪匹配在很多sed版本里不支持(比如非GNU的sed基本都不兼容) - 缺少循环处理:sed默认只会执行一次替换,而你需要多次替换直到行内没有符合条件的空格为止
正确的sed命令
这里给你一个可以实现需求的命令,同时适配大多数sed版本:
sed -E ':loop s/^([^|]{10,}[^ ]) /\1|/; t loop' new.file
命令详解
让我拆解一下每个部分的作用:
-E:启用扩展正则表达式,这样我们不用对括号()和量词{}做转义,写起来更简洁:loop:定义一个循环标签,用于重复执行替换操作s/^([^|]{10,}[^ ]) /\1|/:核心替换规则^:从当前行的起始位置(或者上次替换后的有效起始位置)开始匹配([^|]{10,}[^ ]):捕获组,用来保留我们需要的内容:[^|]{10,}:匹配至少10个不是|的字符(因为已经替换过的部分用|分隔,这样我们就不会重复处理已经分隔好的内容)[^ ]:再匹配一个非空格字符,确保我们找到的空格是在至少10个字符之后的第一个空格(也就是最近的那个空格)
- 最后匹配的
(空格)就是我们要替换的目标,把它换成|,同时保留捕获组里的内容\1
t loop:如果上一次替换操作成功执行了,就跳转到loop标签继续循环,直到没有符合条件的空格可以替换为止
验证示例
用你给出的输入测试:
输入:Hello there! How are you? I am trying to figure this out.
执行命令后得到的输出和你的预期完全一致:
输出:Hello there!|How are you?|I am trying|to figure this|out.
内容的提问来源于stack exchange,提问作者Yuldash Yusupov
相关产品推荐
相关产品推荐

