目录中的总行数

9
我有一个包含成千上万个文件的目录(现在有100K个文件)。当我使用wc -l ./*命令时,会得到以下结果:
 c1            ./test1.txt
 c2            ./test2.txt
 ...
 cn            ./testn.txt
 c1+c2+...+cn  total

由于目录中有很多文件,我只想看到总数而不是详细信息。有没有办法这样做?

我尝试了几种方法,但出现了如下错误:
参数列表太长


快速简单的解决方案可能是 ls -l | wc -l - Guest
1
@Guest,感谢您的回复。我尝试了一下,它显示的是n而不是c1+c2+...+cn - Shannon
3
"cat * | wc -l" 是吗?我很确定这是一个重复的问题。该命令会计算所有文件的总行数。 - Benjamin W.
1
@BenjaminW。它适用于目录中的少量文件。我的目录中有很多文件,因此我会收到“参数列表过长”的错误。 - Shannon
这个回答解决了你的问题吗?如何递归地计算一个目录中所有代码行数? - Josh Correia
7个回答

14
如果你只想要总行数而不需要其他信息,我建议使用以下命令:
cat * | wc -l

这个命令将当前工作目录中所有文件的内容连接起来,并通过wc -l将结果文本块传输。

我觉得这个命令非常优雅。请注意,该命令不会产生任何多余的输出。

更新:

我没有意识到你的目录中有这么多文件。鉴于这个信息,你应该尝试这个命令:

for file in *; do cat "$file"; done | wc -l

大多数人不知道可以将for循环的输出直接传递给另一个命令。
请注意,这可能会非常慢。如果你有大约10万个文件,我猜大约需要10分钟。这只是一个猜测,因为它取决于我无法检查的几个参数。
如果你需要更快的速度,你应该用C语言编写自己的实用程序。如果使用pthread,它可能会出乎意料地快。
希望对你有所帮助。
最后注意:
如果你有兴趣构建一个自定义实用程序,我可以帮你编写一个。这将是一个很好的练习,其他人可能会发现它有用。

唯一的问题是 cat * 无法捕获隐藏(点)文件。cat * .[^.]* 可以获取两者。 - David C. Rankin
@lifecrisis 对于目录中的少量文件它是有效的。我的目录中有很多文件,所以我会得到一个“参数列表太长”的错误。 - Shannon
@DavidC.Rankin,如果问题要求包含点文件,则这将非常有用。请注意,您应该将模式“..?*”添加到命令中。就目前而言,您的模式将无法匹配诸如“..file”之类的文件。 - lifecrisis
当你在S.O.上回答问题时,你就扮演了老师的角色。更好的答案将解释答案的细微差别以及与另一种方法相比的潜在缺点。这有助于学习。虽然问题没有明确要求dotfiles,但也没有明确排除它们。按照写作方式,你的答案是如何对目录中所有文件的行求和的部分答案。 - David C. Rankin
1
@lifecrisis 感谢您提供完整的解释和更新。系统已经停机几天了。当它重新启动时,我会尝试并告诉您结果。 - Shannon
@Shabnam,你发现它特别慢吗? - lifecrisis

5

致谢:这基于@lifecrisis的答案,并对其进行扩展以处理大量文件:

find . -maxdepth 1 -type f -exec cat {} + | wc -l

find 命令可以在当前目录中查找所有文件,将它们分组,并尝试将尽可能多的文件作为参数传递给 cat 命令进行处理。


Davission,请您简要解释一下,“.”是什么意思?它是否表示在当前目录中搜索? - Shannon
@Shabnam 是的,"." 表示当前目录。请参阅"关于目录中的单点和双点" - Gordon Davisson
1
我给这个程序点赞。它非常快,比我之前提到的“for”循环更好地处理了负载。我也没有意识到“find”会为你将文件分成组。这是一个很好的知识点! - lifecrisis
2
@lifecrisis 是的,这是find的一个方便功能。请注意,-exec cmd {} +会批处理运行文件,而-exec cmd \;会逐个运行它们。+的行为非常类似于xargs - Gordon Davisson
@GordonDavisson 感谢您的解释。系统将停机几天。当它重新开始工作时,我会尝试并让您知道。 - Shannon

4
awk 'END {print NR" total"}' ./*

要进行一项有趣的比较,了解有多少行没有以换行符结尾。

将awk和Gordon的find方案结合起来,避免"."文件。

find ./* -maxdepth 0 -type f -exec awk 'END {print NR}' {} +

我不知道这样做是好还是坏,但它确实提供了更准确的计数(对我而言),并且不会计算“.”文件中的行。使用“./ *”只是一个似乎有效的猜测。

仍然需要深度,“./ *”需要“0”深度。

我用“cat”和“awk”解决方案得到了相同的结果(使用相同的查找方式),因为“cat *”处理了换行符问题。我没有一个有足够多文件的目录来测量时间。有趣的是,我喜欢“cat”解决方案。


有许多方法可以做到这一点... 第一个想法是在 wc 上使用“tail - 1”或“grep total”管道,第二个想法是 awk 更准确,因为 wc 只计算以换行符结尾的行。 - JDQ
这在许多地方都是重复的。有许多不同的方法来做到这一点。我发现使用awk解决方案比在我的桌面目录中使用任何wc解决方案都多了六行。 - JDQ
@Gordon Davission:我尝试了,但是出现了以下错误:“参数列表太长”。 - Shannon
听起来您需要一个脚本来循环遍历所有文件。仅凭命令行,您能做的事情是有限的。有多少个文件? - JDQ
抱歉,我用的手机手指太粗,眼睛也不好。 - JDQ
显示剩余2条评论

1
这将为您提供当前目录中所有文件(包括隐藏文件)的总计数:
$ find . -maxdepth 1 -type f  | xargs wc -l  | grep total
 1052 total

要计算不包括隐藏文件的文件,请使用:

find . -maxdepth 1 -type f  -not -path "*/\.*"  | xargs wc -l  | grep total

如果我不想要隐藏文件的信息,我该如何编辑这行代码? - Shannon
@Shabnam:然后使用 -not -path "*/\.*" 来排除当前目录中的隐藏文件。请查看更新后的答案。 - Rahul Verma

1

很抱歉以回答的形式添加此内容,但我没有足够的声望来发表评论。

关于@lifecrisis的答案的评论。也许cat会稍微减慢速度。我们可以用wc -l替换cat,然后使用awk添加数字。(这可能会更快,因为需要通过管道传输的数据要少得多。)

就是这样

for file in *; do wc -l "$file"; done | awk '{sum += $1} END {print sum}'

代替

for file in *; do cat "$file"; done | wc -l

(免责声明: 我没有采纳其他答案中的许多改进,但我认为这个观点足够重要,值得写下来。)

以下是我的结果供比较(我先运行了更新的版本,以便任何缓存效应都会对新的候选者产生影响)。

$ time for f in `seq 1 1500`; do head -c 5M </dev/urandom >myfile-$f |sed -e 's/\(................\)/\1\n/g'; done

real    0m50.360s
user    0m4.040s
sys 0m49.489s

$ time for file in myfile-*; do wc -l "$file"; done | awk '{sum += $1} END {print sum}'
30714902

real    0m3.455s
user    0m2.093s
sys 0m1.515s

$ time for file in myfile-*; do cat "$file"; done | wc -l
30714902

real    0m4.481s
user    0m2.544s
sys 0m4.312s

0

以下命令将提供路径中所有文件的行总数

for i in    `ls- ltr | awk ‘$1~”^-rw”{print $9}’`; do wc -l $I | awk ‘{print $1}’; done >>/var/tmp/filelinescount.txt  
Cat /var/tmp/filelinescount.txt| sed -r “s/\s+//g”|tr “\n” “+”| sed “s:+$::g”| sed ’s/^/“/g’| sed ’s/$/“/g’ | awk ‘{print “echo” “ “ $0”+bc”}’| sh

0

如果你只想知道目录中总行数(不包括空行),可以使用以下命令:

ls -ltr | sed -n '/total/!p' | awk '{print NR}'

前面的评论将给出总行数,其中仅包括所有文件中的行数


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接