How to Loop Through Files in Bash Directory? [With Examples]

LINUX
FUNDAMENTALS
A Complete Guide for Beginners Enroll Course Now

The procedure to loop through files is:

  1. Firstly the directory path of the files should be specified.
  2. Then iterate over the files using the loop.
  3. Process the file to print the name, and read the file.

The basic syntax of the loop-through file is shown below:

directory="directory_path"
for file in "$directory"; do
  echo "$file"
done

OR, 

find "$directory" | while read -r file; do
  echo "$file"
done

Ways to Loop Through Files in Directory

Looping through files in a specific directory refers to the process of iterating over each file and showing the contents of the directory, counting the number of files, and managing files more efficiently. It is important for efficient file management, customized operations, and file processing. Let’s see some basic looping methods through files in a directory:

Using “while” Loop Through Files

To loop through files in a specific directory to print all the names of files use the while loop. Go through the following code:

#!/bin/bash
directory_path="/home/oishi/all_file"
files=$(find "$directory_path" -type f)
counter=1
while IFS= read -r file; do
  echo "$counter: $file"
  ((counter++))
done <<< "$files"
EXPLANATION

Here the find command locates only the files which is ensured by using-type fas mentioned. The while loop reads the files in the directory and the echo command will print the file path and the number of the specified directory. Here counter will show the count of the files which increases withcounter++until the loop ends. The<<<redirects the input from the"$files"into the while loop. The<<<operator is a here-string.

Showing the files in a directory using while loop

The files in the all_file directory have been displayed with the file number.

You can combine the find command with the while loop to print the file name in a directory. Here it is:

#!/bin/bash
directory_path="/home/oishi/All file"
find "$directory_path" -type f | while IFS= read -r file; do
  echo "$file"
done

The output of the code will be the same as the previous one. As the count of the file has not been added here then it will not show the count.

Using a “for” Loop with Wildcard Expansion

The wildcard expansions are the characters that are used to search a pattern or matching text on string data. It is also used for regular expression. The command wildcards are Asterisk (*), question mark (?), and square brackets ([]).

To loop through all the files in a directory use*with for loop. Use the following code:

#!/bin/bash
directory_path="/home/oishi"
for file in "$directory_path"/*; do
  if [ -f "$file" ]; then
    echo "$file"
  fi
done
EXPLANATION

The path of the specified directory is/home/oishi. The for loop iterates over each file, which is ensured by the-foption, and matches the file directory with/home/oishi/*. Theechocommand prints the filename of the directory.

Loop through files in directory with wildcard

Note: It iterates over the files in the directory and does not recursively go through into the files that are in the subdirectories.

If you want to do the input from the command line then you can replace the directory path with an argument. Copy the following code:

#!/bin/bash
directory_path="$1"
for file in "$directory_path"/*; do
  if [ -f "$file" ]; then
    echo "$file"
  fi
done
EXPLANATION

Thedirectory_pathhas been set to the first command line argument with the$1variable.

Loop through files in a specific directory using command line

From the output, you can see if you execute the bash script with any directory path then it will show all the files of the directory.

Note: If your input directory name contains space then the above command won’t show the result. In this case, use the following command:

bash wildcard2.sh "/home/oishi/All script"

Run the script with a directory which has space in name

How to Loop Through Hidden Files in a Directory?

Hidden files are the files in a directory whose name starts with a dot (.). These files are not displayed or viewed by the user. The dot at the beginning of the file makes the file hidden from the normal list of a directory.

Loop through files in a directory to include the hidden file. You can use the following code:

#!/bin/bash
directory_path="/home/oishi"
for file in "$directory_path"/* "$directory_path"/.*; do
  if [ -f "$file" ]; then
    echo "Processing file: $file"
  fi
done
EXPLANATION

Theforloop iterates over the files in thedirectory_pathand also includes the hidden files in the directory. Only the files will be displayed and it is ensured by the-foption.

Showing the hidden files using loop through files in directory All the files including the hidden files have been shown.

To see only the hidden file, run the code:

#!/bin/bash
directory_path="/home/oishi"
for file in "$directory_path"/.*; do
  if [ -f "$file" ] && [ "$(basename "$file")" != "." ] && [ "$(basename "$file")" != ".." ]; then
    echo "Hidden file: $file"
  fi
done
EXPLANATION

The for loop iterates over the specified directory_path. The-f "$file"checks if it is a regular file. The"$(basename "$file")" != "."indicates the file’s basename is not equal to the current directory (.). And the  "$(basename "$file")" != ".."ensures the file’s basename is not equal to the parent directory (..).

Showing the hidden files using loop in bashOnly the hidden files have been shown.

How to Loop Through Files in a Directory Excluding Files of a Specific Pattern?

To exclude a special pattern of files, loop over the files in a directory. Here is how:

#!/bin/bash
directory="/home/oishi"
pattern="*.css"
for file_path in "$directory"/*; do
  if [[ "$file_path" != $pattern ]]; then
    echo "$file_path"
  fi
done
EXPLANATION

Theforloop iterates over the files in the directory. In the[[ "$file_path" != $pattern ]],it matches the file_path with the pattern variable. The selected pattern is the files that have an.css extension. If it does not match with the pattern then it will print the files with theechocommand.

Exclude special pattern of files from showing

From the image you can see, that the specific pattern has been excluded.

Note: Keep this in mind if you excluded a specific pattern it doesn’t mean it is deleted. Only it won’t be displayed.

Count Files by Looping in Directory

Counting the number of files in a directory is important for monitoring resources, and cleaning up and maintaining the system.

To count the file number, loop through the files of the directory. Use the following code.

#!/bin/bash
directory_path="/home/oishi/all_file"
file_count=0
for file_path in "$directory_path"/*; do
  if [ -f "$file_path" ]; then
    ((file_count++))
  fi
done
echo "Number of files in $directory_path: $file_count"
EXPLANATION

The initial file count is set as 0. The for loop iterates over the files in the directory and selects content if it is a regular file which is defined by the-foption and incremented by 1 until the loop ends.

Count of files using loop through files in directory

The count of the files in the /home/oishi/all_file directory is 16.

Loop Through Files Recursively

Loop through files recursively means to display or see the contents of a directory and the nested sub-directories. When you want to perform operations on a file that is in a nested directory then it is important to use a loop recursively.

To loop through files recursively use the following code:

#!/bin/bash
directory="/home/oishi"
function iterate() {
local dir="$1"
for file in "$dir"/*; do
  if [ -f "$file" ]; then
    echo "$file"
  fi
  if [ -d "$file" ]; then
    iterate "$file"
  fi
done
}
iterate "$directory"
EXPLANATION

A function named iterate is declared in which groups of code are available. The local dir is assigned to the first argument. Theforloop iterates over the files and inside the loop, the$file variable is checked if it is a file or not. If it is a file then it is displayed and anotherifstatement is used to check if it is a directory if it is true then it calls the iterate function recursively which processes the sub-directory. Once the loop ends, the function is called with the argument directory.

Recursive looping into the files of a directory

All the files and the subdirectories files have been displayed. In the directory/home/oishi, there are nested subdirectories all_file in which All script directories are present. So with this loop, one can print nested directory files.

Note: Using this code, the empty subdirectories can not be printed.

Practical Examples of Using Loop Through Files in a Directory

Here are some practical examples of using a loop to iterate through files in a directory.

How to Change a File Extension?

Loop through the files can be used to change a file extension. Use the following code to change the file extension.

#!/bin/bash
directory="/home/oishi/Videos"
for file in "$directory"/*.css; do
  if [ -f "$file" ]; then
    mv "$file" "${file%.css}.jsx"
  fi
done
EXPLANATION

The for loop iterates on the/home/oishi/Videosdirectory with a.cssextension. If the if statement is true then the extension.csswill be replaced with an extension.jsx.

Use the ls Videos command to see the contents in the Videos directory:
Before extension changing using loop

Execute the script to change the extension.

Extension using loop through files in directory

From the image you can see the extension has been changed.

How to Clean Old Files Using a Loop?

To clean old files, loop through the files and use the rm command. Here is a sample script:

#!/bin/bash
directory="/home/oishi/Videos"
find "$directory" -type f -mtime +1 -print0 | while read -r -d '' file; do
rm "$file"
done
EXPLANATION

The find command located the file in the directory which is older than 1 day. The -print0 option is used to separate the output with a null character. If any file is located that is older than 1 day then it will be removed by the rm command.

To see all the files before removing them, use thelscommand following the directory.

Before removing the older files using loop

Execute the script to remove files.

Remove files using loop

From the output, you can see that except for the files the other files are deleted.

Conclusion

In this article, looping through the files in a directory has been shown in detail. The flexibility of the loop enables efficient automation and customization. You can use loops to print the content, count files, display hidden files, and include and exclude files to enhance the handling of files.

People Also Ask

How do you check if there are files in a directory in Bash?

To check a main directory and its subdirectories whether contain a file or not, use the if-else statement and loop with the-fand-doption. The-foption will check whether it is a file or not. Here is a sample script:

#! /bin/bash
shopt -s nullglob
main_directory="/home/oishi/Videos"
if [ -d "$main_directory" ]; then
  files=("$main_directory"/*)
if (( ${#files[@]} )); then
  echo "Main directory '$main_directory' contains files"
else
  echo "Main directory '$main_directory' does not contain files"
fi
for sub_directory in "$main_directory"/*/; do
  files=("$sub_directory"/*)
  if (( ${#files[@]} )); then
    echo "Subdirectory '$sub_directory' contains files"
  else
    echo "Subdirectory '$sub_directory' does not contain file"
  fi
done
else
  echo "Main directory does not exist: $main_directory"
fi

Here,shopt -senables thenullgloboption which ensures there are no matching files in the glob pattern. Firstly it checks if the main directory exits or not. If it returns true then it will check whether the main directory contains a file or not. It uses an array(files=("$main_directory"/*))to store the list of files in the main directory. Using${#files[@]}, the length of the array is checked and if it is greater than 0 then it returns the output that it contains the file. The for loop iterates over each subdirectory in the main directory. Similarly, it checks if there are any files in each subdirectory using the for loop.

The main problem of this procedure is if the main directory does not contain any files then it counts the sub-directory as a file and shows that the main directory contains files otherwise it performs properly.

How do I loop through only directories in bash?

To loop through only the directories you can use the following code:

#!/bin/bash
for dir in *; do
  if [ -d "$dir" ]; then
    echo "$dir"
  fi
done

Theforloop iterates over all the files and directories in the current directory and checks whether an item is a directory or not. If it is true then execute theechocommand and print the directories only.

How to loop through the files and directory non-recursively?

To loop through all files non-recursively you can use the following code:

#!/bin/bash
for file in *; do
  echo "$file"
done

Theforloop iterates over all files and directory in the current directory and print all the contents of the current directory.

How to check an empty directory in bash?

To check whether a directory is empty, use the following command:

#!/bin/bash
parent_directory="/home/oishi/Videos"
for directory in "$parent_directory"/*; do
  if [ -d "$directory" ]; then
    if find "$directory" -type d -empty | read -r; then
      echo "Directory '$directory' is empty."
    else
      echo "Directory '$directory' is not empty"
    fi
  fi
done

The loop iterates over the parent directory and all the contents. It checks if it is a directory or not. If the output is true then it will execute the following if statement in which it checks whether the directory is empty or not using the find command. The-type densures it is a directory and -emptychecks if the directory is empty. Thereadcommand takes the output of thefindcommand and prints the output using theechocommand.

How can I read a file located in a specific directory?

To read a file from a specific directory copy the following code:

#! /bin/bash
IFS=''
while read -r line; do
  echo $line
done < "/home/oishi/Videos/all files ggj/colors.txt"

Here the read command is used to read the file and its input is the< "/home/oishi/Videos/all files ggj/colors.txt". Inside the loop, theechocommand is used to print each line of the file. The-roption is used to prevent the backslash as an escape character. TheIFSis set as an empty string for not trimming the white space.

Related Articles


<< Go Back to Bash File & Directory Operations | Bash Files and Directories | Bash Scripting Tutorial

5/5 - (2 votes)
Afia Zahin Oishi

Assalamualaikum, I am Afia Zahin, completed my graduation in Biomedical Engineering from Bangladesh University of Engineering and Technology, currently working as a Linux Content Developer Executive at SOFTEKO. A high achieving professional with a strong work ethic and able to work in a team in order to consistently achieve my goal and build my skillset. Able to handle difficult problems with patience and swift decision-making. Read Full Bio

Leave a Comment