Bash for Each File in a Directory

Written by: Bobbin Zachariah   |   Last updated: May 29, 2023

In this tutorial, we will explore the versatility of Bash for loops and learn how to effectively iterate over files in a directory. By using a wildcard expression, such as an asterisk (*), we can effortlessly loop through all the entries in a directory and perform file manipulation tasks.

We will walk through practical examples that demonstrate the power of Bash for loops, including displaying file extensions and renaming files with specific extensions.

Syntax

Bash for loop when used with the wildcard expression asterisk (*) will loop through all the entries of the directory and in each step store that entry in a variable. 

Here’s the syntax:

for file in * 
do 
	…
	…
	…
done

Iterate over files using for loop

The Bash for loops has made the task of looping through the contents of any directory effortless. We can consider this as iterating over elements of the array. Let us understand this process in detail. 

The first thing needed is to create a directory. Let us create a directory named "MyDir'' using the mkdir command. Then we need to enter this directory using the cd command.

mkdir MyDir
cd MyDir
create a sample directory named MyDir

We create files in this directory as follows:

echo "Adding contents to file1" > file1.xls
echo "Adding contents to file2" > file2.xls
echo "Adding contents to file3" > file3.xls
echo "Adding contents to file4" > file4.xls
create a set of sample files with some raw data

Now that we have everything ready, we can easily loop through the files present in this directory using the for loop with the wildcard asterisk (*). 

Example:

#!/bin/bash 
for file in * 
do
echo $file - `head -1 $file`
done
Bash script code demonstrating a for loop iterating over files in a directory and printing their names along with the first line

We have used the wildcard character asterisk (*) to build the for loop expression. This is the beauty of Bash. It allows regular expressions in its loops. The asterisk informs the for loop to consider every single file in the directory.

The variable "file" is the iterator which will pick up the entries of the directory one by one. It then prints the name of the file followed by the first line in that file using the head command.

Example Scripts

We learned how the for loop works with a simple example. Now, we will look at a couple of real-world problems where we will write and understand bash scripts to bring this theory to practice.

Display extension of each file in a directory

In the following example, the script prompts the user for the directory path . After checking its existence it lists the extensions of all the files present. 

Example:

#!/bin/bash 

read -p "Enter the directory path: " dpath


if [ ! -d "$dpath" ]
then
	echo "Invalid directory. Please check the input."
else
	contentsOfDir=`ls`
for content in $contentsOfDir
do
	if [ -d $content ]
	then
		echo $content is a directory and will not have any extension
	else
		ext=`echo ${content#*.}`
		echo "$content has extension: "$ext
	fi
done
fi
Bash script prompting the user to enter a directory path and displaying file extensions for each file in the directory

1. The execution of the script starts by prompting the user to enter the directory path. This is done by the read command and it stores the response in the variable named dpath.

2. The script verifies if the user input is a directory or not using the -d test condition on the variable dpath. If the path is non-existent, it prints "Invalid directory path. Please check the input."

3. If the file exists, the script fetches all the contents of that directory and stores it in the variable contentsofDir using the backticks technique.

4. The script runs a for loop for all the contents present in that directory. The for loop iterator is named content.

5. In every iteration, the script checks if the content is a file or directory. If it is a directory, it displays that the current value of the iterator is a directory and will not have any extension.

6. If it is a file (not a directory), the script will extract the extension using the parameter expansion and store the result in the ext variable.

7. For each iteration, it will finally print the name of the file and the extension it has.

Rename files with specific extension

The script prompts the user for the directory path. After checking its existence it asks the user to provide the old and new extension. Based on that it rename those files with the new extensions 

Example:

#!/bin/bash 

read -p "Enter the directory path: " dpath


if [ ! -d "$dpath" ]
then
	echo "Invalid directory. Please check the input."
else
	read -p "Enter the extension you want to replace: " oldExt
	read -p "Enter the new extension you want: " newExt
	for entry in $dpath/*
	do
	if [ ! -d $entry ]
	then
		ext=`echo ${entry#*.}`
		if [ "$ext" = "$oldExt" ]
		then
	filename=`basename -s $ext $entry`
		mv $entry ${filename}${newExt}
		echo ${filename}${newExt} in ${dpath} is renamed to ${filename}${newExt}
	fi
		fi
	done
fi
Bash script prompting the user to enter a directory path and rename files with a specific extension to a new extension

1. The script begins by using the read command to prompt the user to enter the directory path. The entered value is stored in the variable named dpath.

2. The script checks if the value present in that variable is a directory or not. It uses the -d test condition in the if expression. If the directory structure is non-existent, it prints "Invalid directory path. Please check the input."

3. If the file exists, the script prompts the user to enter the old extension that has to be renamed. This response is stored in the oldExt variable.

4. The script looks for the new extension from the user. This response is held by the newExt variable.

5. The script runs a for loop for every entry in the provided path. The iterator is named as "entry" and is assigned the task of looping through all the contents of the directory one at a time.

6. The script first verifies that the input is a file or directory in each for loop run. It is ignored and the iterator points to the next entry, if it is a directory,  

7. The script pulls out the extension of the file and stores it in the variable named "ext", if it is a file.

8. The script then does a comparison of the value present in the oldExt and the ext variables.

9. Only if they match, the script extracts the name of the file using the basename command.

10. It then moves the filename present in the iterator to ${filename}${newExt}.

11. By the end of the script, all the files will get renamed with the new extension.

About The Author

Bobbin Zachariah

Bobbin Zachariah

Bobbin Zachariah is an experienced Linux engineer who has been supporting infrastructure for many companies. He specializes in Shell scripting, AWS Cloud, JavaScript, and Nodejs. He has qualified Master’s degree in computer science. He holds Red Hat Certified Engineer (RHCE) certification and RedHat Enable Sysadmin.

SHARE

Comments

Please add comments below to provide the author your ideas, appreciation and feedback.

Leave a Reply

Leave a Comment