I'm new to this with shellscript and Linux and now I'm stuck. I shall write a simple program that allows me to search for andy file extension I want and then display how many of them there are.
I've been searching the net and read the book I've got but I just can't figure it out.

This is what I got so far:


#Program to search for how many of specific file extension there is in this directory.

echo "Write the file extension you want to search for:"
read n

for n in `ls *.txt` ; do
  echo $n

I'm suppose to use a for loop.

How do I continue from here?


As mentioned already find is usually the correct tool when handling files. It can however be perfectly OK.

You can skip this part of printf if you want, only include it as a bonus :P

One thing that you also can start using is printf. It is generally a better option then echo. In its simplest form you have:

printf "Some text\n"

where \n is new-line. If you want to print some variable you can use the special symbol %s (for string):

printf "Name is %s \n" "$name"
              |           |
              |           +---- value
              +---------------- format string

printf "Name is %s city is %s \n" "$name" "$city"
              |                      |       |
              |                      +-------+----- values
              +------------------------------------ format string

There are other symbols you can use, such as %d (for digit). You can also use other special characters such as \t (tab).

For you code it is generally better to use the newer $(cmd) instead of ``cmd`. In your code that would be:

$(ls *.txt)

Next thing to look at is the for loop. Your statement

for n in `ls *.txt`; do

does not do what you think. Here n is treated as a variable name to which the result of ls *.txt is assigned. If you have the files:


The execution of the code would expand to:

for n in a.txt b.txt c.txt; do

That is: for each iteration n is set to the next file name. You end up with:

n=a.txt  (first loop)
n=b.txt  (second loop)
n=c.txt  (last loop)

If we collect this together we can for example write something like this:


printf "Write the file extension you want to search for: "
read ext

printf "Searching for files with extension '%s'\n" "$ext"

for file in *"$ext"; do
    printf "File: %s\n" "$file"

Or you can simply say:

ls *"$ext"

Note that the asterisk is outside the quotes. Else it won't expand.

  • Also, using for n in $(ls *.txt) is unnecessary, just use for n in *.txt. ls is just repeating the list of files that the shell already expanded. Not that you need a loop in this case...
    – orion
    Jan 13 '15 at 8:12

You should probably use find. Something like:

echo "Write the file extension you want to search for:"
read n
find . -name "*.$n"

Anyway, what you probably intended to do was:

for i in *."$n"
    echo "$i"

Otherwise, you're not using the value of n (instead using the fixed extension txt), and overwriting the read value of n in the for loop,

  • Thanks. I forgot to mention that it is suppose to be a for-loop. So I wrote this and it works, but it only gives me the output: "*.sh" when for example searching for file extension sh.
    – Anileve
    Jan 13 '15 at 6:47
  • @Anileve That happens when no matches were found. *.sh remains unexpanded if there are no files matching that pattern.
    – muru
    Jan 13 '15 at 7:02
  • Ah of course =)
    – Anileve
    Jan 13 '15 at 7:22

You can do it:

echo -n "Write the file extension you want to search for:"
read n
find $1 -iname "*.$n" -print 

usage :

./myscript.sh mypath

Output is :

root@debian:/home/mohsen/test# ./myscript.sh /home/mohsen
Write the file extension you want to search for:sh
/home/mohsen/Downloads/binary files/apt-fast_aria2c.sh
/home/mohsen/Downloads/binary files/apt-fast.sh
/home/mohsen/Downloads/binary files/toggle_touchpad.sh
/home/mohsen/Downloads/binary files/nvidia-versions.sh

A single line command:

echo "Enter file extension:"  
for f in `find <some_path> -name "*$(read n; echo $n)"` ; do echo $f ; done

search for andy file extension I want and then display how many of them there are

You don't need a loop for that at all. Assuming there are no newline characters inside file names you can write

wc -l < <(ls *."$n")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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