Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell how many files match description with * in unix

Tags:

string

bash

unix

Pretty simple question: say I have a set of files:

a1.txt
a2.txt
a3.txt
b1.txt

And I use the following command:

ls a*.txt

It will return:

a1.txt a2.txt a3.txt

Is there a way in a bash script to tell how many results will be returned when using the * pattern. In the above example if I were to use a*.txt the answer should be 3 and if I used *1.txt the answer should be 2.

like image 855
Fantastic Mr Fox Avatar asked Nov 25 '25 21:11

Fantastic Mr Fox


2 Answers

Comment on using ls:

  1. I see all the other answers attempt this by parsing the output of ls. This is very unpredictable because this breaks when you have file names with "unusual characters" (e.g. spaces).
  2. Another pitfall would be, it is ls implementation dependent. A particular implementation might format output differently.

There is a very nice discussion on the pitfalls of parsing ls output on the bash wiki maintained by Greg Wooledge.

Solution using bash arrays

For the above reasons, using bash syntax would be the more reliable option. You can use a glob to populate a bash array with all the matching file names. Then you can ask bash the length of the array to get the number of matches. The following snippet should work.

files=(a*.txt) && echo "${#files[@]}"

To save the number of matches in a variable, you can do:

files=(a*.txt)
count="${#files[@]}"

One more advantage of this method is you now also have the matching files in an array which you can iterate over.

Note: Although I keep repeating bash syntax above, I believe the above solution applies to all sh-family of shells.

like image 176
suvayu Avatar answered Nov 27 '25 14:11

suvayu


You can't know ahead of time, but you can count how many results are returned. I.e.

  ls -l *.txt | wc -l

ls -l will display the directory entries matching the specified wildcard, wc -l will give you the count.

You can save the value of this command in a shell variable with either

  num=$(ls * | wc -l)

or

  num=`ls -l *.txt | wc -l`

and then use $num to access it. The first form is preferred.

like image 25
Levon Avatar answered Nov 27 '25 14:11

Levon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!