这似乎是一项相当简单的任务,但我找不到一个快速可靠的解决方案.

我有bash中的字符串,我想知道将在终端上打印的字符数.我之所以需要这样做,是为了将字符串很好地对齐在三列中,每列n个字符.为此,我需要添加尽可能多的"空格",以确保第二列和第三列始终从终端中的同一位置开始.

字符串长度有问题的示例:

v='féé'

echo "${#v1}"
 > # 5 (should be 3)

printf '%s' "${v1}" | wc -m
 > # 5 (should be 3)

printf '%s' "${v1}" | awk '{print length}'
 > # 5 (should be 3)

我找到的最好的是这个,它可以工作most of the time.

echo "${v}" | python3 -c 'v=input();print(len(v))'
 > # 3 (yeah!)

但有时,我的角色会被以下几个序列修改.我不能在这里复制/越过它,但它看起来是这样的:

v="de\314\201tresse"
echo "${v}"
 > # détresse
echo "${v}" | python3 -c 'v=input();print(len(v))'
 > # 9 (should be 8)

我知道使用\r个字符或ANSI序列可能会更复杂,但我只需要处理在文件名、文档和其他人类编写的文件内容中常见的"常规"字符串.由于字符串是在终端中打印的,我猜一定有某个引擎知道或可以知道字符串的打印长度.

我也考虑了可能的解决方案,发送ANSI序列来获取打印字符串前后光标在终端中的位置,并使用差异来计算长度,但它看起来像一个我不想挖的兔子洞.此外,这将是非常缓慢的.

推荐答案

怎么样

v='féé'
echo "${v}" | python3 -c 'import unicodedata as ud;v=input();print(len(ud.normalize("NFC",v)))'

如果您在安装时遇到问题

pip install unicodedata

try unicodedata2

Additional Notes

这将根据解释here的NFC标准将字符串标准化为UTF-8.如果您使用的是拉丁语ANSI,那么它应该工作得很好.但是,对于UNICODE ANSI之前的语言编码,如阿拉伯语、希腊语、 hebrew 、俄语或泰语,则NFC可能会保留原始格式.虽然使用NFC通常更可取,但在这些情况下您也可以try 使用NFKC. Select nfc的原因是为了避免规格化兼容但不规范等价的符号,例如单字符ff(U+fb00):如果使用nfc对其进行规格化,则长度为1,但如果使用nfc对其进行规格化,则长度为2.根据您的应用程序的不同,这可能会产生一些问题,但如果您只想要可读的文本,那么nfkc是可以的.

Python相关问答推荐

tempfile.mkstemp(text=.)参数实际上是什么?

用ctype构建指针链

Pandas .类型错误:只能将字符串(而不是int)连接到字符串

Pandas数据帧处理Pandas表中Json内的嵌套列表以获取后续Numpy数组

使用decorator 自动继承父类

脚注在Python中使用regex导致错误匹配

来自ARIMA结果的模型方程

使用Python OpenCV的文本检测分割

如何在Python中按组应用简单的线性回归?

过载功能是否包含Support Int而不是Support Int?

从今天起的future 12个月内使用Python迭代

使用LineConnection动画1D数据

将numpy数组存储在原始二进制文件中

Pydantic 2.7.0模型接受字符串日期时间或无

如何使用Python将工作表从一个Excel工作簿复制粘贴到另一个工作簿?

需要计算60,000个坐标之间的距离

ModuleNotFound错误:没有名为flags.State的模块; flags不是包

如何制作10,000年及以后的日期时间对象?

Python键入协议默认值

Scrapy和Great Expectations(great_expectations)—不合作