Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

if you have something like:

find . -d -maxdepth 1 | wc -l | perl ...

what ways do you have to tell perl to take this variable that's coming its way and substract 1?

I try to substract 1 since find is counting 1 too much.

share|improve this question
This does what you ask for: pastebin.com/9ACX3vxW But I doubt this is a solution of the real problem. – manatwork Apr 2 '13 at 13:54
I am betting what you are really looking for is -mindepth 1. You often need to explain what you want, rather than how you are trying to implement it. – jordanm Apr 2 '13 at 13:59
Perl is also the wrong tool for the job. bc is what should be used here (or straight shell script $(( ... )). – Patrick Apr 2 '13 at 14:02
@manatwork: that's what I wanted. Indeed, the question is not about finding anything, but about learning how perl oneliners get variables passed from a pipe. – xyz Apr 2 '13 at 14:20
up vote 3 down vote accepted

Perl would be overkill here.

find . -maxdepth 1 -mindepth 1 | wc -l

(better use grep -c / instead of wc -l in case some filenames have newline characters in them).

Or with GNU ls:

ls -A | wc -l

With zsh:

echo $#f

To remove one:

... | tail -n +2 | wc -l


n=$(... | wc -l); echo "$(($n - 1))"

With perl, you can use the -n or -p flag:

... | perl -lpe '--$_'

Above that --$_ expression is evaluated and the content of the $_ variable printed for each line of input.

share|improve this answer

There is a reason why you get the wrong answer. In this case I expect you want to count the directory entries and not see the directory itself listed, as is represented by the single dot line which is the last line of output from find.

A solution would be to hide entries that should not be counted from "wc -l", example

find .  -depth -maxdepth 1 | grep -v "^\.$" | wc -l

Since grep can count the lines, you can use that to save the need to launch an additional executable, example

find . -depth -maxdepth 1 | grep -vc "^\.$"

Since the number of items found does not change based on wheter you traverse depth first or not, you can eliminate that option, giving you

find . -maxdepth 1 | grep -vc "^\.$"
share|improve this answer

I agree with the other answers, perl is overkill for what you seem to be looking for. That said, certainly there are legitimate reasons for passing a bash variable to perl. Use export and perl's environment variable, along these lines:

# i=$(find . -d -maxdepth 1 | wc -l) ; export i=$i ; perl -le 'print "Removing one from  $ENV{i} for ".($ENV{i}-=1)'; unset i 

For a numerical solution from shell:

# i=$(find . -d -maxdepth 1 | wc -l) ; echo i=$((i-1))
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.