正确计算 bash 变量的行数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23736555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 10:28:51  来源:igfitidea点击:

Correctly count number of lines a bash variable

bashshellwc

提问by linkyndy

I need to count the number of lines of a given variable. For example I need to find how many lines VARhas, where VAR=$(git log -n 10 --format="%s").

我需要计算给定变量的行数。例如,我需要找到有多少行VAR,在哪里VAR=$(git log -n 10 --format="%s")

I tried with echo "$VAR" | wc -l), which indeed works, but if VARis empty, is prints 1, which is wrong. Is there a workaround for this? Something better than using an ifclause to check whether the variable is empty...(maybe add a line and subtract 1 from the returned value?).

我试过echo "$VAR" | wc -l),确实有效,但如果VAR为空,则为 prints 1,这是错误的。有解决方法吗?比使用if子句检查变量是否为空更好的东西......(也许添加一行并从返回值中减去 1?)。

回答by jm666

The wccounts the number of newline chars. You can use grep -c '^'for counting lines. You can see the difference with:

wc计数换行字符的数量。您可以grep -c '^'用于计数线。你可以看到不同之处:

#!/bin/bash

count_it() {
    echo "Variablie contains : ==><=="
    echo -n 'grep:'; echo -n "" | grep -c '^'
    echo -n 'wc  :'; echo -n "" | wc -l
    echo
}

VAR=''
count_it "$VAR" "empty variable"

VAR='one line'
count_it "$VAR" "one line without \n at the end"

VAR='line1
'
count_it "$VAR" "one line with \n at the end"

VAR='line1
line2'
count_it "$VAR" "two lines without \n at the end"

VAR='line1
line2
'
count_it "$VAR" "two lines with \n at the end"

what produces:

什么产生:

Variablie contains empty variable: ==><==
grep:0
wc  :       0

Variablie contains one line without \n at the end: ==>one line<==
grep:1
wc  :       0

Variablie contains one line with \n at the end: ==>line1
<==
grep:1
wc  :       1

Variablie contains two lines without \n at the end: ==>line1
line2<==
grep:2
wc  :       1

Variablie contains two lines with \n at the end: ==>line1
line2
<==
grep:2
wc  :       2

回答by nemo

You can always write it conditionally:

你总是可以有条件地写:

[ -n "$VAR" ] && echo "$VAR" | wc -l || echo 0

This will check whether $VARhas contents and act accordingly.

这将检查是否$VAR有内容并采取相应措施。

回答by gniourf_gniourf

For a pure bash solution: instead of putting the output of the gitcommand into a variable (which, arguably, is ugly), put it in an array, one line per field:

对于纯 bash 解决方案:不是将git命令的输出放入变量(这可以说是丑陋的),而是将其放入一个数组中,每个字段一行:

mapfile -t ary < <(git log -n 10 --format="%s")

Then you only need to count the number of fields in the array ary:

然后你只需要计算数组中的字段数ary

echo "${#ary[@]}"

This design will also make your life simpler if, e.g., you need to retrieve the 5th commit message:

如果例如您需要检索第 5 个提交消息,则此设计还将使您的生活更简单:

echo "${ary[4]}"

回答by Taher Khorshidi

try:

尝试:

echo "$VAR" | grep ^ | wc -l