列出按文件包含的行数排序的文件


32

如何列出中文件/group/book/four/word的行数,按文件包含的行数排序?

ls -l 命令将其列出,但不对其进行排序


1
您要按行数列出文件,还是列出文件中的行数,或同时列出两者?ls -l没有给出行数。ls -lS通过一些ls实现按大小对文件进行排序(大小是内容中的字节数)。
斯特凡Chazelas

Answers:


34

您应该使用如下命令:

find /group/book/four/word/ -type f -exec wc -l {} + | sort -rn
  • find:在所需路径上搜索文件。如果您不希望它递归,并且您的find实现支持它,则应-maxdepth 1在该-exec选项之前添加。
  • exec:告诉命令wc -l在每个文件上执行。
  • sort -rn:以相反的顺序对结果进行数字排序。从大到小。

(假设文件名不包含换行符)。


请注意,当传递多个文件(或在某些实现中,它可以读取的多个文件)时,wc也会打印total一行,因此在这里,除非只有一个文件,否则您还将获得一个或多个“总计”行。 。您可以通过管道将grep /其删除。
斯特凡Chazelas

sort命令而投票
弗朗西斯科·弗朗西斯科

如何过滤以仅显示最少X行的文件(例如,排除X = 0行)?
Matrix

11

非递归

如果您不需要递归,可能是最简单的版本:

wc -l /group/book/four/word/*|sort -n

wc在下的-l每个(但隐藏的)(*)文件中对行(选项)进行计数/group/book/four/word/,并对sort结果(通过pipe |)进行数字排序(选项-n)。

递归的

有人对此答案进行了评论grep -rlc,然后加以压制。确实grep是一个不错的选择,尤其是在需要递归的情况下:

grep -rc '^' /group/book/four/word/|tr ':' ' '|sort -n -k2

将对目录中与()(即行的开头)相匹配的行(option -c)进行递归计算(option )。然后,您必须用一个空格代替冒号,例如,使用,以帮助您要在第二列(选项)上按数字排序的(选项)-rgrep'^'/group/book/four/word/trsort-n-k2))。

更新:请参阅Stephane关于可能存在的限制以及如何真正摆脱的评论tr


3
grep -c .计算至少包含一个有效字符的行。使用grep -c '^'计算所有线路(也将计算与一些最后的换行后尾随字符grep实现)。请注意,并非所有的grep实现都支持,-r并且行为之间也有所不同。您无需将:s(冒号,而不是分号)转换为的空格sort。只需使用-t:。请注意,这假定文件名不包含:空格或换行符。
斯特凡Chazelas

1
感谢您发布您的非递归解决方案;wc如果您通过多条路径,我不知道能给您这么方便的总数。将该功能与通配符和管道连接起来sort真的很干净。
Qcom 2015年

7

zsh

lines() REPLY=$(wc -l < $REPLY)
printf '%s\n' /group/book/four/word/*(.no+lines)

我们定义了一个新的排序功能lines,该功能可以响应文件中的行数。并且我们使用o+linesglob限定符,该限定符与n(用于数字排序)一起定义了glob结果的排序方式。(.也添加到仅检查常规文件)。

这样就不会假设文件名除了隐藏文件(以开头的那些文件.)以外还可以包含什么字符,这些假设都将被忽略。D如果需要,请添加glob限定符。


2
OP bash仅带有标签...
l0b0

7
@ l0b0并不意味着下一个需要此功能的人也将运行bash。
terdon

4

您无需指定是否还需要文件的任何子目录中的文件/group/book/four/wordfindjherran的答案中的解决方案将归为子目录。如果不需要,请使用外壳程序代替:

for file in ./*; do [ -f "$file" ] && wc -l "$file"; done | sort -n

如果您的文件名可以包含换行符,则可以使用以下内容:

for file in ./*; do 
    [ -f "$file" ] && 
        printf "%lu %s\0" "$(wc -l < "$file")" "$file"
done | sort -zn | tr '\0' '\n'

最后,如果您确实想进入子目录,则可以在bash4或更高版本中使用它:

shopt -s globstar
for file in ./**/*; do [ -f "$file" ] && wc -l "$file"; done | sort -n

需要注意的是版本bash之前的4.3进行下面的符号链接时,递归下降目录树(如zsh的或tcsh***/*)。

另外,以上所有解决方案都将忽略隐藏文件(名称以a开头的文件.,用于shopt -s dotglob包含它们),还将包括符号链接的行数(该find方法不会)。


请注意,与jherran解决方案的其他不同之处在于,您还将考虑对常规文件(-xtype f在GNU find或*(-.)zsh中)的符号链接,并将省略隐藏文件。
斯特凡Chazelas

@StéphaneChazelas感谢,澄清了。为什么%luprintf?我记得这意味着长无符号十进制,真的有必要吗?为什么不将数字视为字符串?这有什么不同吗?
terdon

2
如果wc输出为空(例如,因为文件不可读),则它将扩展为,0而不是空字符串,这会稍好一些。有些排序实现使用无符号整数,有些带有符号。%lu听起来像是最安全的选择,但好像没有2^31台词无关紧要,但这仍然需要一段时间。
斯特凡Chazelas

1

如果您想安装fd一个用Rust编写的非常快速的文件查找器(您应该安装它,无论如何都很好)

fd --type=file . | xargs wc -l | sort -n

基本上fd列出文件,xargs会将文件列表传递给wc(代表字数统计,但传递-l将使它计数行数),最后将它按行数从最小到最大的顺序进行排序sort -n

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.