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
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
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
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
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
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.
Comments