Loop Through Files in Directory in Bash
Razvan Ludosanu
Founder, learnbackend.dev
Published: 5/16/2024
The short answer
To create a Bash script that loops through files in a specified directory and prints their path, you can start by creating a new file using the touch command:
$ touch iterate.sh
Run in Warp
And copy-paste the following script into it, that will:
- 1. Check if the target is a valid directory or exit with a return value of 1, which in Unix translates to “something went wrong”.
- 2. Create a for loop that iterates over each file of the target directory.
- 3. Check if the current file is a regular file.
- 4. Write the file path to the standard output using the echo command.
#!/bin/bash
# Define the target directory
directory="/path/to/directory"
# Check if the target is not a directory
if [ ! -d "$directory" ]; then
exit 1
fi
# Loop through files in the target directory
for file in "$directory"/*; do
if [ -f "$file" ]; then
echo "$file"
fi
done
Run in Warp
To be able to run the script, you then have to give it execution permission using the chmod command:
$ chmod +x iterate.sh
Run in Warp
Finally, you can run the script using the following command:
$ ./iterate.sh
Run in Warp
If you want to learn more advanced formatting options, you can read our article on the printf utility.
If you're new to Unix permissions, you can also read our other article on the chmod +x command.
Using Warp's AI to quickly retrieve these steps
If you’re using Warp as your terminal, you can easily retrieve an approximation of the above script using Warp's AI feature:
For that:
- 1. Click on the bolt icon on the top right of the terminal
- 2. Type in your question; for example: "Write a Bash script that prints the name of files in a directory".
- 3. Press ENTER to generate an answer.
As with any AI-powered tool, use it as a starting point and not a final answer.
Including and excluding files
Including hidden files
Since, by default, hidden files are not listed, you can add the following shopt command (short for shell options) to the script, right before the for loop, to enable Bash to include dot files in the result of the filename expansion.
#!/bin/bash
directory="/path/to/directory"
shopt -s dotglob
for file in "$directory"/*; do
if [ -f "$file" ]; then
echo "$file"
fi
done
Run in Warp
Including files based on a pattern
To only include files that match a specific pattern (e.g. JavaScript or JSON files), you can use a pattern variable that contains a globbing expression as follows:
#!/bin/bash
directory="/path/to/directory"
pattern="*.json"
for file in "$directory"/$pattern; do
if [ -f "$file" ]; then
echo "$file"
fi
done
Run in Warp
Excluding files based on a pattern
To exclude files that match a specific pattern, you can use a combination of a while loop, and the find and read commands, where:
- The find command will return a string of characters containing the paths of the regular files that do not match the specified pattern in the target directory, each followed by a trailing null character.
- The read command will split the data sent by the find command through the pipe into multiple entries using the -d option flag, so that they can be written to the standard output by the echo command.
#!/bin/bash
directory="/path/to/directory"
pattern="*.json"
find "$directory" -type f ! -name "$pattern" -print0 -maxdepth 1 | while read -r -d '' file; do
echo "$file"
done
Run in Warp
Note that you can make this script recursively descend in the sub-directories of the target directory by changing the value of the -maxdepth option flag.
Looping through files recursively
To loop through files in a directory and its subdirectories, you can write a recursive function that takes as initial argument the path of the target directory, iterates through each entry of the current directory, and invokes itself whenever that entry is a directory.
#!/bin/bash
directory="/path/to/directory"
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"
Run in Warp
Looping through lines in a file
To loop through the lines of a regular file, you can use the read command, which is used to read a line from the standard input and split it into fields, where the -r option flag is used to prevent backslashes to escape characters.
#!/bin/bash
file="/path/to/file"
while IFS= read -r line; do
echo "$line"
done < "$file"
Run in Warp
Note that, setting the IFS (Internal Field Separator) variable to an empty value ensures that leading and trailing whitespace characters are preserved in the input line.
Common use cases
Here are a few examples of common loops you may find useful when iterating over files.
Changing file extensions
This loop will change the file extension of JavaScript files from .js to .jsx.
#!/bin/bash
directory="/path/to/directory"
for file in "$directory"/*.js; do
if [ -f "$file" ]; then
mv "$file" "${file%.js}.jsx"
fi
done
Run in Warp
Cleaning up old files
This loop will delete all the files that are older than 30 days.
#!/bin/bash
directory="/path/to/directory"
find "$directory" -type f -mtime +30 -print0 | while read -r -d '' file; do
rm "$file"
done
Run in Warp
Extracting data from a CSV file
This loop will extract the email addresses contained in a CSV file and write them into a new file named emails.txt.
#!/bin/bash
file="/path/to/file"
while IFS=',' read -r first_name last_name email_address phone_number; do
echo "$email_address" >> emails.txt
done < "$file"
Run in Warp
Looping through files in Python
To re-implement the introduction script in Python, you can write the following code into a new file named iterate.py:
import os
directory = '/path/to/directory'
if not os.path.isdir(directory):
exit(1)
for filename in os.listdir(directory):
filepath = os.path.join(directory, filename)
if os.path.isfile(filepath):
print(f"{filepath}")
Run in Warp
And run it using the python CLI as follows:
$ python3 iterate.py
Run in Warp
Written by
Razvan Ludosanu
Founder, learnbackend.dev
Filed Under
Related Articles
Bash If Statement
Learn how to use the if statement in Bash to compare multiple values and expressions.
Bash While Loop
Learn how to use and control the while loop in Bash to repeat instructions, and read from the standard input, files, arrays, and more.
POST JSON Data With Curl
How to send valid HTTP POST requests with JSON data payloads using the curl command and how to avoid common syntax pitfalls. Also, how to solve the HTTP 405 error code.
Use Cookies With cURL
Learn how to store and send cookies using files, hard-coded values, environment variables with cURL.
How To Use sudo su
A quick overview of using sudo su
Generate, Sign, and View a CSR With OpenSSL
Learn how to generate, self-sign, and verify certificate signing requests with `openssl`.
How to use sudo rm -rf safely
We'll help you understand its components
How to run chmod recursively
Using -R is probably not what you want
Run Bash Shell In Docker
Start an interactive shell in Docker container
Curl Post Request
Use cURL to send data to a server
Reading User Input
Via command line arguments and prompting users for input
Bash Aliases
Create an alias for common commands