如何打印文本文件每行的字符数

Posted

技术标签:

【中文标题】如何打印文本文件每行的字符数【英文标题】:How to print the number of characters in each line of a text file 【发布时间】:2012-02-05 21:10:41 【问题描述】:

我想使用 unix 命令打印文本文件每行中的字符数。我知道使用 powershell 很简单

gc abc.txt | % $_.length

但我需要 unix 命令。

【问题讨论】:

【参考方案1】:

使用 Awk。

awk ' print length ' abc.txt

【讨论】:

这比对每一行应用 wc -c 快几个数量级! @aerijman 对于这类问题,进程创建的数量通常是最大的性能差异。 如果文件中的一行包含表情符号,则不会产生预期的长度。 @user5507535,这取决于您实际期望的“长度”。 Unicode 有很多可能的定义(mawk 使用字节,没有检查 gawk)。【参考方案2】:
while IFS= read -r line; do echo $#line; done < abc.txt

它是 POSIX,所以它应该可以在任何地方工作。

编辑:按照 William 的建议添加了 -r。

编辑:注意 Unicode 处理。正确设置语言环境的 Bash 和 zsh 将显示代码点的数量,但 dash 将显示字节 - 所以你必须检查你的 shell 做了什么。无论如何,Unicode 中还有许多其他可能的长度定义,所以这取决于你真正想要的。

编辑:前缀IFS= 以避免丢失前导和尾随空格。

【讨论】:

+1,但是...如果输入包含“\”,这将失败。使用 read -r 如果文件中的一行包含表情符号,则不会产生预期的长度。 @user5507535,实际上,这取决于您期望的“长度”。 Unicode 有许多可能的定义(但在这种情况下,不同的 shell 实际上会做不同的事情)。 当想要读取任意数据时,始终在read 命令上设置IFS=。所以IFS= read -rread 使用 IFS 进行分词,即使所有拆分后的词都被重新粘贴到一个可用变量 (line) 中,也不能保证它们与所有原始词一起粘贴回来他们拥有的分隔符或只有一个可能不同的分隔符。例如,使用默认 IFS,行 foo bar 可能变为 foo bar,丢失 7 个空格。 (就像 Stack Overflow 如何在此注释中丢失该示例字符串中的相邻空格一样)。 @mtraceur,文档明确指出“剩余的单词及其中间分隔符被分配给姓氏”,因此它们确实与原始分隔符一起粘贴回来。但是,这并没有处理确实丢失的 leadingtrailing 分隔符。所以你是对的,应该设置IFS,但是不设置的问题更微妙。【参考方案3】:

这是使用xargs的示例:

$ xargs -d '\n' -I% sh -c 'echo % | wc -c' < file

【讨论】:

这个 "echo %" 不处理需要从 shell 引用的不安全字符。此外,“xargs”将按空格和换行符分割您的文件,而不仅仅是原始海报要求的换行符。【参考方案4】:

我已经尝试了上面列出的其他答案,但在处理大文件时它们与体面的解决方案相去甚远——尤其是当单行的大小占用超过 ~1/4 的可用 RAM 时。

bash 和 awk 都在整行,即使对于这个问题,它不是必需的。一旦一行太长,即使你有足够的内存,Bash 也会出错。

我已经实现了一个非常简单、相当未经优化的 python 脚本,当用大文件(每行约 4 GB)进行测试时,它不会乱七八糟,而且是比给定的解决方案更好的解决方案。

如果这是用于生产的时间关键代码,您可以在测试这确实是一个瓶颈之后,用 C 重写这些想法或对读取调用执行更好的优化(而不是一次只读取一个字节)。

代码假定换行符是换行符,这对于 Unix 是一个很好的假设,但在 Mac OS/Windows 上是 YMMV。确保文件以换行符结尾,以确保不会忽略最后一行字符数。

from sys import stdin, exit

counter = 0
while True:
    byte = stdin.buffer.read(1)
    counter += 1
    if not byte:
        exit()
    if byte == b'\x0a':
        print(counter-1)
        counter = 0

【讨论】:

问题是针对“文本”文件。我认为每行 4GB 不适合文本文件的任何合理定义。【参考方案5】:

试试这个:

while read line    
do    
    echo -e |wc -m      
done <abc.txt    

【讨论】:

你的意思是echo -e | wc -m,不是吗?使用命令是无用的; shell 可以对变量中的字符进行计数。另外,echo -e 完全不兼容,并且可以在一半的 shell 中工作,而从一些转义序列开始,在其他一些 shell 中可以工作,其余的则什么都没有。

以上是关于如何打印文本文件每行的字符数的主要内容,如果未能解决你的问题,请参考以下文章

批处理如何提取文本文件中每行字符串,每行单独存放不同文本中?

linux文本如何统计列数

python读取文本文件,如何将每行最后一个特定字符替换?

如何在C++中 统计多行文本中的行数、单词数及字符数

如何将数组的内容写入文本文件,每行一个数据?

在另一个文本文件中存在的文本之后打印特定行