Вопрос

I'd like to run a find command and then count the lines of the output as well as give out the output of the result. My straight-forward approach was this:

output=$(find ...)
lines=$(echo "$output" | wc -l)
echo "$output"

But unfortunately using echo to pipe this into wc adds a newline, so even if the find did not find anything (zero lines of output), that wc is giving out 1 (for the newline which the echo appended.

I changed the echo to a printf to prevent appending the newline to the output but then also a one-line output of find like var/ was without a newline, and hence the wc gave out 0.

The problem is in the capturing of the output ($(...)). It strips trailing newlines which in my case are relevant.

Can this be prevented somehow?

Is there a completely different approach on my original task?

Это было полезно?

Решение 3

I'm now using a workaround by appending a fake line to the output; this way I can rely on the fact that one line will always be present, and this way the empty line is easily distinguishable from the one-line:

r=$(find var/ -name var -printf "%p\n"; echo '==')
# appending additional line to be able to distinguish 0 from 1 found file
case "$(echo "$r" | wc -l)" in
  1)  # means 0 found files
    ...
  2)  # means 1 found file
    ...
  *)  # means more found files
    ...
esac

Другие советы

A simple workaround that would occur to mind would be to check if the string is empty:

[ -z "$output" ] && count=0 || count=$(wc -l <<< "$output")

Now count would be 0 if find didn't produce any output else it would contain the number of lines in the output.

Counting new lines after storing find's output in a variable is always going to be problematic in case your file names contain spaces or new lines.

I would suggest using find like this (to count all *.txt files and print them)

output=
c=0

while read -d ''; do 
    ((c++))
    output+="$REPLY"$'\n'
done < <(find . -name "*.txt" -print0)

echo "c=$c"
echo "output=$output"

PS: This will also take care of new lines/spaces in file names.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top