如何使用`wc -l`获得一行?

Ehr*_*ryk 13 xargs files wc

我添加了一个 git 别名,以提供我历史记录中特定文件的行数:

[alias]
lines = !lc() { git ls-files -z ${1} | xargs -0 wc -l; }; lc
Run Code Online (Sandbox Code Playgroud)

但是,wc -l正在报告多个总数,如果我有超过 10 万行,它会报告它们的总数,然后继续。下面是一个例子:

<100k 行(所需输出)

$ git lines \*.xslt
  46 packages/NUnit-2.5.10.11092/doc/files/Summary.xslt
 232 packages/NUnit-2.5.10.11092/samples/csharp/_UpgradeReport_Files/UpgradeReport.xslt
 278 total
Run Code Online (Sandbox Code Playgroud)

> 100k 行(必须通过管道传输grep "total"

$ git lines \*.cs | grep "total"
 123569 total
 107700 total
 134796 total
 111411 total
  44600 total
Run Code Online (Sandbox Code Playgroud)

如何从 中获得真正的总计wc -l,而不是一系列小计?

ric*_*ici 13

试试这个,并为显而易见的道歉:

cat *.cs | wc -l
Run Code Online (Sandbox Code Playgroud)

或者,使用 git:

git ls-files -z ${1} | xargs -0 cat | wc -l
Run Code Online (Sandbox Code Playgroud)

如果您确实希望输出看起来像wc输出,同时具有单个计数和总和,则可以使用awk将各个行相加:

git ls-files -z ${1} | xargs -0 wc -l |
awk '/^[[:space:]]*[[:digit:]]+[[:space:]]+total$/{next}
     {total+=$1;print}
     END {print total,"total"}'
Run Code Online (Sandbox Code Playgroud)

wc如果这对您很重要,那将不会像它那样排列整齐。为此,您需要读取整个输入并保存它,计算总数,然后使用总数计算字段宽度,然后使用该字段宽度打印记住行的格式化输出。就像家庭装修项目一样,awk脚本永远不会真正完成。

(热心的编辑请注意:第一个awk条件中的正则表达式是以防文件名以“total”和空格开头;否则,条件可能会简单得多$2 == "total"。)


Mar*_*ick 7

如果您正在运行 Linux,则您wc可能来自 GNU Coreutils,并且可以--files0-from选择读取包含任意长的 NUL 终止文件名称列表的文件(或标准输入)以进行计数。在GNU Coreutils的WC文件说,“这是非常有用的,当文件名的名单很长,所以它可能超过命令行长度的限制。在这种情况下,在运行通过xargs的厕所是不可取的,因为它将该列表成片,使WC打印每个子列表的总数,而不是整个列表。”

所以试试这个:

lc() { git ls-files -z ${1} | wc -l --files0-from=- ; } 
Run Code Online (Sandbox Code Playgroud)

编辑:由于您wc来自上一千年并且没有该选项,因此这里有一个更便携的解决方案,假设您有awk并且没有任何名为“total”的文件。它将过滤 的输出wc,省略任何total行,而是将它们相加并在最后打印出总计。

我不知道的一件事是git别名实现是否会在单引号$1$2内部出现问题,需要不变地传递给awk.

lc() {
  git ls-files -z ${1} |
  xargs -0 wc -l |
  awk 'BEGIN { total=0; } { if (NF==2 && $2 == "total") total += $1; else print; } END { print total, "total"; }' ;
}
Run Code Online (Sandbox Code Playgroud)