在Bash中,如何输出一个文件的行数而不包括文件名,同时使用一个Bash变量来表示该文件?

82

我在一个bash脚本中有以下三个结构:

NUMOFLINES=$(wc -l $JAVA_TAGS_FILE)
echo $NUMOFLINES" lines"

echo $(wc -l $JAVA_TAGS_FILE)" lines"

echo "$(wc -l $JAVA_TAGS_FILE) lines"

当脚本运行时,它们都会产生相同的输出:

121711 /home/slash/.java_base.tag lines
121711 /home/slash/.java_base.tag lines
121711 /home/slash/.java_base.tag lines

例如,文件名也被回显了(这不是我想要的)。为什么这些脚本会失败,我应该如何输出干净的内容:
121711 lines

?


可能是在bash中从wc获取整数的重复问题。 - Ciro Santilli OurBigBook.com
6个回答

160

使用自己的数据的示例

您可以通过从JAVA_TAGS_FILE进行重定向,而不是将文件名作为参数传递给wc,来避免将您的文件名嵌入到NUMOFLINES变量中。例如:

NUMOFLINES=$(wc -l < "$JAVA_TAGS_FILE")

解释:使用管道或重定向来避免在输出中显示文件名

wc实用程序如果从管道或重定向操作符接收输入,则不会在其输出中打印文件名。考虑以下各种示例:

# wc shows filename when the file is an argument
$ wc -l /etc/passwd
41 /etc/passwd

# filename is ignored when piped in on standard input
$ cat /etc/passwd | wc -l
41

# unusual redirection, but wc still ignores the filename
$ < /etc/passwd wc -l
41

# typical redirection, taking standard input from a file
$ wc -l < /etc/passwd
41

正如你所看到的,只有当文件名被作为参数传递而不是作为标准输入的数据时,wc 才会打印文件名。在某些情况下,你可能希望打印文件名,因此了解何时会显示它非常有用。


2
请注意,如果最后一行没有结束符,则此方法将不包括最后一行。请参考以下修复措施。 - ling

15

wc 如果你没有给它文件名,就无法获取文件名。

wc -l < "$JAVA_TAGS_FILE"

2
那就不要这样做。按照答案中所示,将文件传递给wc的标准输入。因此,可以使用cat "$JAVA_TAGS_FILE" | wc -l或等效地使用wc -l < "$JAVA_TAGS_FILE"。这样,wc只会得到原始数据,而不是文件名。 - Witiko

12

您也可以使用awk:

awk 'END {print NR,"行"}' 文件名

或者

awk 'END {print NR}' 文件名


6
(适用于Mac和其他Unix系统)
实际上,使用wc的方法存在一个问题:如果最后一行没有以换行符结束,则不会计算它。
改用以下方法:
nbLines=$(cat -n file.txt | tail -n 1 | cut -f1 | xargs)

甚至更好(感谢gniourf_gniourf):
nblines=$(grep -c '' file.txt)

注意:chilicuil的awk方法也很有效。

3
方法过于复杂!也许你想使用nblines=$(grep -c '' file)代替(这是在这种情况下计算不完整行的规范方法)。但请注意,根据POSIX标准,您正在计算不完整行,而不是。实际上,您正在处理二进制文件而不是文本文件 - gniourf_gniourf
@gniourf_gniourf 谢谢,我不知道那个,它很好用,而且更加简洁。 - ling
可能有更好的解决方案:nblines=$(($(cat "file.txt" | wc -l) + 1)) - Andrey Izman

3

这是一个非常简单的任务:

NUMOFLINES=$(cat $JAVA_TAGS_FILE | wc -l )

或者

NUMOFLINES=$(wc -l $JAVA_TAGS_FILE | awk '{print $1}')

第一个是无用的 cat 用法。 - kap
@kap 不是的,它只是看起来像这样。如果你去掉 cat,那么你就会得到第二个例子,因为 wc -l 只在与文件一起使用时返回 2 列。 - Slava Semushin

-3

我通常使用bash的“反引号”功能

export NUM_LINES=`wc -l filename`

请注意,'tick'是'back tick',例如`而不是普通的单引号。

5
那只是不同的表述方式,不能解决文件名成为结果的一部分的问题。 - Izzy

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