Reputation: 17900
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
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
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
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