如何实现POSIX兼容的Shell字符串中间截断(带UTF-8省略号)?
符合POSIX标准的Shell字符串截断实现
需求说明
我需要在Shell脚本中实现:当字符串长度超过9个字符时,将其转换为总长度9的格式——保留前4个字符、后4个字符,中间用UTF-8省略号(…)连接;长度≤9时保持原字符串不变。
示例:
foobarSN9保持为foobarSN9foobarSN10转换为foob…SN10
我当前的非POSIX兼容代码
str="foobarSN10" strlen=$(echo -n "$str" | wc -m) delim=$'\u2026' test $strlen -gt 9 && echo "$str" | sed 's/\(.\{4\}\).*\(.\{4\}\)/\1'$delim'\2/' || echo "$str"
POSIX兼容的最简实现
str="foobarSN10" delim=$(printf '\342\200\246') [ $(expr length "$str") -gt 9 ] && echo "$str" | sed "s/^\(.\{4\}\).*\(.\{4\}\)$/\1$delim\2/" || echo "$str"
关键兼容点说明
- 字符长度获取:用
expr length "$str"替代wc -m——expr length是POSIX标准命令,返回字符串的字符数(支持多字节UTF-8字符),而wc -m属于GNU扩展,并非所有POSIX系统都支持。 - 省略号定义:用
printf '\342\200\246'生成UTF-8省略号——$'\u2026'是bash/ksh专属的扩展语法,POSIX Shell不支持,直接使用UTF-8对应的八进制转义序列,能保证跨系统兼容。 - Sed正则适配:使用
^\(.\{4\}\).*\(.\{4\}\)$的完整匹配正则,避免部分字符串被错误截断;POSIX标准Sed的基本正则中,\{n\}是合法的量词写法,无需额外修改。
内容的提问来源于stack exchange,提问作者Martin Braun
相关产品推荐
相关产品推荐

