FUNDAMENTALS A Complete Guide for Beginners
The procedure to loop through files is:
- Firstly the directory path of the files should be specified.
- Then iterate over the files using the loop.
- 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"
Here the find command locates only the files which is ensured by using-type f
as 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.
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
The path of the specified directory is/home/oishi
. The for loop iterates over each file, which is ensured by the-f
option, and matches the file directory with/home/oishi/*
. Theecho
command prints the filename of the directory.
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
Thedirectory_path
has been set to the first command line argument with the$1
variable.
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"
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
Thefor
loop iterates over the files in thedirectory_path
and also includes the hidden files in the directory. Only the files will be displayed and it is ensured by the-f
option.
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
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 (..).
Only 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
Thefor
loop 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 theecho
command.
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"
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-f
option and incremented by 1 until the loop ends.
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"
A function named iterate is declared in which groups of code are available. The local dir is assigned to the first argument. Thefor
loop 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 anotherif
statement 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.
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.
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
The for loop iterates on the/home/oishi/Videos
directory with a.css
extension. If the if
statement is true then the extension.css
will be replaced with an extension.jsx
.
Use the ls Videos
command to see the contents in the Videos directory:
Execute the script to change the extension.
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
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 thels
command following the directory.
Execute the script to remove files.
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-f
and-d
option. The-f
option 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 -s
enables thenullglob
option 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
Thefor
loop 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 theecho
command 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
Thefor
loop 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 d
ensures it is a directory and -empty
checks if the directory is empty. Theread
command takes the output of thefind
command and prints the output using theecho
command.
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, theecho
command is used to print each line of the file. The-r
option is used to prevent the backslash as an escape character. TheIFS
is set as an empty string for not trimming the white space.
Related Articles
- How to Read Files in Bash [4 Methods]
- How to Append to File in Bash [5 Methods]
- How to Echo Multiline to a File in Bash [3 Methods]
<< Go Back to Bash File & Directory Operations | Bash Files and Directories | Bash Scripting Tutorial