linkyndy
linkyndy

Reputation: 17900

Correctly count number of lines a bash variable

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

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

Upvotes: 7

Views: 7392

Answers (4)

gniourf_gniourf
gniourf_gniourf

Reputation: 46813

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

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

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

echo "${#ary[@]}"

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

echo "${ary[4]}"

Upvotes: 5

Farvardin
Farvardin

Reputation: 5414

try:

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

Upvotes: 2

clt60
clt60

Reputation: 63892

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

#!/bin/bash

count_it() {
    echo "Variablie contains $2: ==>$1<=="
    echo -n 'grep:'; echo -n "$1" | grep -c '^'
    echo -n 'wc  :'; echo -n "$1" | 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

Upvotes: 14

nemo
nemo

Reputation: 57609

You can always write it conditionally:

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

This will check whether $VAR has contents and act accordingly.

Upvotes: 7

Related Questions