3

I'm pretty sure this is going to be obvious, but currently im doing this:

count=`find $dir -type f \( -perm -007 \) -print 2>/dev/null | wc -l`

This gets me the number i want, but dosen't display anything on screen (although i chuck away error lines anyhow).

Is there a way to do this (obtain the wc -l count into count variable) while also displaying the output to the console, in one command ? I'm pretty sure something like tee could be used here, but my brain isn't working like it should.

Otherwise, i guess writing to a temp file and console using tee and cat it back into wc would work, but I'm pretty convinced there must be a more elegant way of doing this.

edit: Sorry, it seems the question was unclear. I don't want to show the count to screen, i want to show the output that i've been counting, i.e: the output from find

Sirex
  • 219
  • 4
  • 22

6 Answers6

6

Ah, so you want to print the normal output, and have the number of matches in $count?

Try this:

count=`find $dir -type f \( -perm -007 \) -print 2>/dev/null | tee /dev/tty | wc -l`
Mikel
  • 24,855
  • 8
  • 65
  • 66
2

Ok, an answer to the updated question then

The tty approach is nice, but will fail over non-terminals (e.g. ssh localhost 'echo hello > /dev/tty' fails)

It could just be

count=`find $dir -type f \( -perm -007 \) -print 2>/dev/null | tee >(cat >&2) | wc -l`

Which is equivalent to

count=`find $dir -type f \( -perm -007 \) -print 2>/dev/null | tee /proc/self/fd/2 | wc -l`

If you don't want to/cannot use stderror (fd 2) as the sidechannel here, then you can open a duplicate of the original stdout and refer to it instead:

exec 3>&1
count=`find $dir -type f \( -perm -007 \) -print 2>/dev/null | tee /proc/self/fd/3 | wc -l`

$0.02

sehe
  • 374,641
  • 47
  • 450
  • 633
  • I like this one. I was trying to remember how to open a duplicate of an existing file handle, and couldn't remember. – David Conrad Apr 06 '11 at 11:26
1

Update I have added another answer after the question had been updated

unset x
echo ${x:="$(find $dir -type f \( -perm -007 \) -print 2>/dev/null | wc -l)"}
echo $x

output

16
16
Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
  • @Paul: really... well I thought the question was about setting the variable while showing it; but i updated the answer for the bleedingly obvious :) – sehe Apr 06 '11 at 08:42
  • Why does this have two upvotes when it doesn't even answer the question? Sirex wanted it to output the results of find, not the count. – David Conrad Apr 06 '11 at 09:03
  • Indeed, [have posted a new answer instead](http://stackoverflow.com/questions/5563491/bash-obtain-wc-l-number-and-display-in-one-command/5564112#5564112) now – sehe Apr 06 '11 at 09:23
1

Here's an answer to your clarified question. This puts the count in variable $count and shows the output of find:

found=$(find $dir type f \( -perm -007 \) -print 2>/dev/null)
count=$(echo -e "$found" | wc -l)
echo -e "$found"
lecodesportif
  • 10,737
  • 9
  • 38
  • 58
0

I'm not sure I completely understand, since the find command, as written, doesn't need the parentheses and shouldn't produce any errors, and I don't know if you need to have the output go to stdout or if you just want to see it working, in which case stderr would work just as well. I would do this:

count=`find $dir -type f -perm -007 -print -fprint /dev/stderr | wc -l`
David Conrad
  • 15,432
  • 2
  • 42
  • 54
0

You can print the output of find to screen, if you tee the stdout of the find command to stderr (here via an anonymous fifo).

If your file names or paths have embedded newlines, your count will go awry. Therefore, use the -print0 feature of find, then delete all bytes that are not '\0' with the tr command, and finally just count the '\0' bytes with the wc command at the very end.

# show output of find to screen
count=`find . -type f \( -perm -007 \) -print0 2>/dev/null | tee >(tr '\0' '\n' > /dev/stderr) | tr -dc '\0' |  wc -c`
echo "$count"

# show output of count to screen
count=`find . -type f \( -perm -007 \) -print0 2>/dev/null | tee >(tr -dc '\0' | wc -c > /dev/stderr) | tr -dc '\0' |  wc -c`
echo "$count"