ℹ️ Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 1.1 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://www.redhat.com/en/blog/bash-scripting-loops |
| Last Crawled | 2026-03-06 16:37:59 (1 month ago) |
| First Indexed | 2024-12-03 07:42:24 (1 year ago) |
| HTTP Status Code | 200 |
| Meta Title | Introduction to Linux Bash programming: 5 `for` loop tips |
| Meta Description | Every sysadmin probably has some skill they've learned over the years that they can point at and say, "That changed my world." That skill, or that bit of inf... |
| Meta Canonical | null |
| Boilerpipe Text | Every sysadmin probably has some skill they've learned over the years that they can point at and say, "That changed my world." That skill, or that bit of information, or that technique just changed how I do things. For many of us, that thing is
looping
in Bash. There are other approaches to automation that are certainly more robust or scalable. Most of them do not compare to the simplicity and ready usability of the
for
loop, though.
If you want to automate the configuration of thousands of systems, you should probably use Ansible. However, if you're trying to rename a thousand files, or execute the same command several times, then the
for
loop is definitely the right tool for the job.
[ You might also like:
Mastering loops with Jinja templates in Ansible
]
If you already have a programming or scripting background, you're probably familiar with what
for
loops do. If you're not, I'll try to break it down in plain English for you.
The basic concept is:
FOR
a given set of items,
DO
a thing.
The given set of items can be a literal set of objects or anything that Bash can extrapolate to a list. For example, text pulled from a file, the output of another Bash command, or parameters passed via the command line. Converting this loop structure into a Bash script is also trivial. In this article, we show you some examples of how a
for
loop can make you look like a command line hero, and then we take some of those examples and put them inside a more structured Bash script.
Basic structure of the for loop
First, let's talk about the basic structure of a
for
loop, and then we'll get into some examples.
The basic syntax of a
for
loop is:
for <variable name> in <a list of items>;do <some command> $<variable name>;done;
The
variable name
will be the variable you specify in the
do
section and will contain the item in the loop that you're on.
The
list of items
can be anything that returns a space or newline-separated list.
Here's an example:
$ for name in joey suzy bobby;do echo $name;done
That's about as simple as it gets and there isn't a whole lot going on there, but it gets you started. The variable
$name
will contain the item in the list that the loop is currently operating on, and once the command (or commands) in the
do
section are carried out, the loop will move to the next item. You can also perform more than one action per loop. Anything between
do
and
done
will be executed. New commands just need a
;
delimiting them.
$ for name in joey suzy bobby; do echo first $name;echo second $name;done;
first joey
second joey
first suzy
second suzy
first bobby
second bobby
Now for some
real
examples.
Renaming files
This loop takes the output of the Bash command
ls *.pdf
and performs an action on each returned file name. In this case, we're adding today's date to the end of the file name (but before the file extension).
for i in $(ls *.pdf); do
mv $i $(basename $i .pdf)_$(date +%Y%m%d).pdf
done
To illustrate, run this loop in a directory containing these files:
file1.pdf
file2.pdf
...
fileN.pdf
The files will be renamed like this:
file1_20210210.pdf
file2_20210210.pdf
...
fileN_20210210.pdf
In a directory with hundreds of files, this loop saves you a considerable amount of time in renaming all of them.
Extrapolating lists of items
Imagine that you have a file that you want to
scp
to several servers. Remember that you can combine the
for
loop with other Bash features, such as shell expansion, which allows Bash to expand a list of items that are in a series. This can work for letters and numbers. For example:
$ echo {0..10}
0 1 2 3 4 5 6 7 8 9 10
Assuming your servers are named in some sort of pattern like,
web0
,
web1
,
web2
,
web3
, you can have Bash iterate the series of numbers like this:
$ for i in web{0..10};do scp somefile.txt ${i}:;done;
This will iterate through
web0
,
web1
,
web2
,
web3
, and so forth, executing your command on each item.
You can also define a few iterations. For example:
$ for i in web{0..10} db{0..2} balance_{a..c};do echo $i;done
web0
web1
web2
web3
web4
web5
web6
web7
web8
web9
web10
db0
db1
db2
balance_a
balance_b
balance_c
You can also combine iterations. Imagine that you have two data centers, one in the United States, another in Canada, and the server's naming convention identifies which data center a server HA pair lived in. For example,
web-us-0
would be the first web server in the US data center, while
web-ca-0
would be
web 0's
counterpart in the CA data center. To execute something on both systems, you can use a sequence like this:
$ for i in web-{us,ca}-{0..3};do echo $i;done
web-us-0
web-us-1
web-us-2
web-us-3
web-ca-0
web-ca-1
web-ca-2
web-ca-3
In case your server names are not easy to iterate through, you can provide a list of names to the
for
loop:
$ cat somelist
first_item
middle_things
foo
bar
baz
last_item
$ for i in `cat somelist`;do echo "ITEM: $i";done
ITEM: first_item
ITEM: middle_things
ITEM: foo
ITEM: bar
ITEM: baz
ITEM: last_item
Nesting
You can also combine some of these ideas for more complex use cases. For example, imagine that you want to copy a list of files to your web servers that follow the numbered naming convention you used in the previous example.
You can accomplish that by iterating a second list based on your first list through nested loops. This gets a little hard to follow when you're doing it as a one-liner, but it can definitely be done. Your nested
for
loop gets executed on every iteration of the parent
for
loop. Be sure to specify different variable names for each loop.
To copy the list of files
file1.txt, file2.txt,
and
file3.txt
to the web servers, use this nested loop:
$ for i in file{1..3};do for x in web{0..3};do echo "Copying $i to server $x"; scp $i $x; done; done
Copying file1 to server web0
Copying file1 to server web1
Copying file1 to server web2
Copying file1 to server web3
Copying file2 to server web0
Copying file2 to server web1
Copying file2 to server web2
Copying file2 to server web3
Copying file3 to server web0
Copying file3 to server web1
Copying file3 to server web2
Copying file3 to server web3
More creative renaming
There might be other ways to get this done, but remember, this is just an example of things you
can
do with a
for
loop. What if you have a mountain of files named something like
FILE002.txt
, and you want to replace
FILE
with something like
TEXT
. Remember that in addition to Bash itself, you also have other open source tools at your disposal, like
sed
,
grep
, and more. You can combine those tools with the
for
loop, like this:
$ ls FILE*.txt
FILE0.txt FILE10.txt FILE1.txt FILE2.txt FILE3.txt FILE4.txt FILE5.txt FILE6.txt FILE7.txt FILE8.txt FILE9.txt
$ for i in $(ls FILE*.txt);do mv $i `echo $i | sed s/FILE/TEXT/`;done
$ ls FILE*.txt
ls: cannot access 'FILE*.txt': No such file or directory
$ ls TEXT*.txt
TEXT0.txt TEXT10.txt TEXT1.txt TEXT2.txt TEXT3.txt TEXT4.txt TEXT5.txt TEXT6.txt TEXT7.txt TEXT8.txt TEXT9.txt
Adding a for loop to a Bash script
Running
for
loops directly on the command line is great and saves you a considerable amount of time for some tasks. In addition, you can include
for
loops as part of your Bash scripts for increased power, readability, and flexibility.
For example, you can add the nested loop example to a Bash script to improve its readability, like this:
$ vim copy_web_files.sh
# !/bin/bash
for i in file{1..3};do
for x in web{0..3};do
echo "Copying $i to server $x"
scp $i $x
done
done
When you save and execute this script, the result is the same as running the nested loop example above, but it's more readable, plus it's easier to change and maintain.
$ bash copy_web_files.sh
Copying file1 to server web0
Copying file1 to server web1
... TRUNCATED ...
Copying file3 to server web3
You can also increase the flexibility and reusability of your
for
loops by including them in Bash scripts that allow parameter input. For example, to rename files like the example
More creative renaming
above allowing the user to specify the name suffix, use this script:
$ vim rename_files.sh
# !/bin/bash
source_prefix=$1
suffix=$2
destination_prefix=$3
for i in $(ls ${source_prefix}*.${suffix});do
mv $i $(echo $i | sed s/${source_prefix}/${destination_prefix}/)
done
In this script, the user provides the source file's prefix as the first parameter, the file suffix as the second, and the new prefix as the third parameter. For example, to rename all files starting with
FILE
, of type
.txt
to
TEXT
, execute the script like this :
$ ls FILE*.txt
FILE0.txt FILE10.txt FILE1.txt FILE2.txt FILE3.txt FILE4.txt FILE5.txt FILE6.txt FILE7.txt FILE8.txt FILE9.txt
$ bash rename_files.sh FILE txt TEXT
$ ls TEXT*.txt
TEXT0.txt TEXT10.txt TEXT1.txt TEXT2.txt TEXT3.txt TEXT4.txt TEXT5.txt TEXT6.txt TEXT7.txt TEXT8.txt TEXT9.txt
This is similar to the original example, but now your users can specify other parameters to change the script behavior. For example, to rename all files now starting with
TEXT
to
NEW
, use the following:
$ bash rename_files.sh TEXT txt NEW
$ ls NEW*.txt
NEW0.txt NEW10.txt NEW1.txt NEW2.txt NEW3.txt NEW4.txt NEW5.txt NEW6.txt NEW7.txt NEW8.txt NEW9.txt
[ A free course for you: Virtualization and Infrastructure Migration Technical Overview. ]
Conclusion
Hopefully, these examples have demonstrated the power of a
for
loop at the Bash command line. You really can save a lot of time and perform tasks in a less error-prone way with loops. Just be careful. Your loops will do what you ask them to, even if you ask them to do something destructive by accident, like creating (or deleting) logical volumes or virtual disks.
We hope that Bash
for
loops change your world the same way they changed ours. |
| Markdown | [Skip to content](https://www.redhat.com/en/blog/bash-scripting-loops#rhdc-main-content)
## Navigation
Menu
AI
- ### Our approach
- [News and insights](https://www.redhat.com/en/blog/channel/artificial-intelligence)
- [Technical blog](https://developers.redhat.com/aiml#ai-ml-main-tab-recent-articles-100491)
- [Research](https://www.redhat.com/en/artificial-intelligence/research)
- [Live AI events](https://www.redhat.com/en/events/ai)
- [Get an overview](https://www.redhat.com/en/artificial-intelligence)
- ### Products
- [Red Hat AI Enterprise](https://www.redhat.com/en/products/ai/enterprise)
- [Red Hat AI Inference Server](https://www.redhat.com/en/products/ai/inference-server)
- [Red Hat Enterprise Linux AI](https://www.redhat.com/en/products/ai/enterprise-linux-ai)
- [Red Hat OpenShift AI](https://www.redhat.com/en/products/ai/openshift-ai)
- [Explore Red Hat AI](https://www.redhat.com/en/products/ai)
- ### Engage & learn
- [AI learning hub](https://docs.redhat.com/en/learn/ai)
- [AI partners](https://catalog.redhat.com/categories/ai#ai-partners)
- [Services for AI](https://www.redhat.com/en/services/consulting/red-hat-consulting-for-ai)
Hybrid cloud
- ### Platform solutions
- [Artificial intelligence](https://www.redhat.com/en/hybrid-cloud-solutions/ai)
Build, deploy, and monitor AI models and apps.
- [Linux standardization](https://www.redhat.com/en/hybrid-cloud-solutions/linux-standardization)
Get consistency across operating environments.
- [Application development](https://www.redhat.com/en/hybrid-cloud-solutions/application-development)
Simplify the way you build, deploy, and manage apps.
- [Automation](https://www.redhat.com/en/hybrid-cloud-solutions/automation)
Scale automation and unite tech, teams, and environments.
- ### Use cases
- [Virtualization](https://www.redhat.com/en/hybrid-cloud-solutions/virtualization)
Modernize operations for virtualized and containerized workloads.
- [Digital sovereignty](https://www.redhat.com/en/products/digital-sovereignty)
Control and protect critical infrastructure.
- [Security](https://www.redhat.com/en/solutions/trusted-software-supply-chain)
Code, build, deploy, and monitor security-focused software.
- [Edge computing](https://www.redhat.com/en/products/edge)
Deploy workloads closer to the source with edge technology.
- [Explore solutions](https://www.redhat.com/en/hybrid-cloud-solutions)
- ### Solutions by industry
- [Automotive](https://www.redhat.com/en/solutions/automotive)
- [Financial services](https://www.redhat.com/en/solutions/financial-services)
- [Healthcare](https://www.redhat.com/en/solutions/healthcare)
- [Industrial sector](https://www.redhat.com/en/solutions/industrial-sector)
- [Media and entertainment](https://www.redhat.com/en/solutions/media-entertainment)
- [Public sector (Global)](https://www.redhat.com/en/solutions/public-sector)
- [Public sector (U.S.)](https://www.redhat.com/en/solutions/public-sector/us)
- [Telecommunications](https://www.redhat.com/en/solutions/telecommunications)
### [Discover cloud technologies](https://www.redhat.com/en/hybrid-cloud-console)
Learn how to use our cloud products and solutions at your own pace in the Red Hat® Hybrid Cloud Console.
Products
- ### Platforms
- [Red Hat AI](https://www.redhat.com/en/products/ai)
Develop and deploy AI solutions across the hybrid cloud.
- [Red Hat Enterprise Linux](https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux)
Support hybrid cloud innovation on a flexible operating system.
- [Red Hat OpenShift](https://www.redhat.com/en/technologies/cloud-computing/openshift)
Build, modernize, and deploy apps at scale.
- [Red Hat Ansible Automation Platform](https://www.redhat.com/en/technologies/management/ansible)
Implement enterprise-wide automation.
- ### Featured
- [Red Hat OpenShift Virtualization Engine](https://www.redhat.com/en/technologies/cloud-computing/openshift/virtualization-engine)
- [Red Hat OpenShift Service on AWS](https://www.redhat.com/en/technologies/cloud-computing/openshift/aws)
- [Microsoft Azure Red Hat OpenShift](https://www.redhat.com/en/technologies/cloud-computing/openshift/azure)
- [See all products](https://www.redhat.com/en/technologies/all-products)
- ### Try & buy
- [Start a trial](https://www.redhat.com/en/products/trials)
- [Buy online](https://www.redhat.com/en/store)
- [Integrate with major cloud providers](https://www.redhat.com/en/partners/certified-cloud-and-service-providers)
- ### Services & support
- [Consulting](https://www.redhat.com/en/services/consulting)
- [Product support](https://www.redhat.com/en/services/support)
- [Services for AI](https://www.redhat.com/en/services/consulting/red-hat-consulting-for-ai)
- [Technical Account Management](https://www.redhat.com/en/services/support/technical-account-management)
- [Explore services](https://www.redhat.com/en/services)
Training
- ### Training & certification
- [Courses and exams](https://www.redhat.com/en/services/training/all-courses-exams)
- [Certifications](https://www.redhat.com/en/services/certifications)
- [Skills assessments](https://skills.ole.redhat.com/en)
- [Red Hat Academy](https://www.redhat.com/en/services/training/red-hat-academy)
- [Learning subscription](https://www.redhat.com/en/services/training/learning-subscription)
- [Explore training](https://www.redhat.com/en/services/training-and-certification)
- ### Featured
- [Red Hat Certified System Administrator exam](https://www.redhat.com/en/services/training/ex200-red-hat-certified-system-administrator-rhcsa-exam)
- [Red Hat System Administration I](https://www.redhat.com/en/services/training/rh124-red-hat-system-administration-i)
- [Red Hat Learning Subscription trial (No cost)](https://www.redhat.com/en/services/training/learning-subscription/trial)
- [Red Hat Certified Engineer exam](https://www.redhat.com/en/services/training/ex294-red-hat-certified-engineer-rhce-exam-red-hat-enterprise-linux)
- [Red Hat Certified OpenShift Administrator exam](https://www.redhat.com/en/services/training/red-hat-certified-openshift-administrator-exam)
- ### Services
- [Consulting](https://www.redhat.com/en/services/consulting)
- [Partner training](https://connect.redhat.com/en/training)
- [Product support](https://www.redhat.com/en/services/support)
- [Services for AI](https://www.redhat.com/en/services/consulting/red-hat-consulting-for-ai)
- [Technical Account Management](https://www.redhat.com/en/services/support/technical-account-management)
Learn
- ### Build your skills
- [Documentation](https://docs.redhat.com/en)
- [Hands-on labs](https://www.redhat.com/en/interactive-labs)
- [Hybrid cloud learning hub](https://cloud.redhat.com/learn)
- [Interactive learning experiences](https://www.redhat.com/en/interactive-experiences)
- [Training and certification](https://www.redhat.com/en/services/training-and-certification)
- ### More ways to learn
- [Blog](https://www.redhat.com/en/blog)
- [Events and webinars](https://www.redhat.com/en/events)
- [Podcasts and video series](https://www.redhat.com/en/red-hat-original-series)
- [Red Hat TV](https://tv.redhat.com/)
- [Resource library](https://www.redhat.com/en/resources)
### [For developers](https://developers.redhat.com/)
Discover resources and tools to help you build, deliver, and manage cloud-native applications and services.
Partners
- ### For customers
- [Our partners](https://www.redhat.com/en/partners)
- [Red Hat Ecosystem Catalog](https://catalog.redhat.com/)
- [Find a partner](https://catalog.redhat.com/partners)
- ### For partners
- [Partner Connect](https://connect.redhat.com/)
- [Become a partner](https://connect.redhat.com/en/benefits-of-being-a-partner)
- [Training](https://connect.redhat.com/en/training)
- [Support](https://connect.redhat.com/en/support)
- [Access the partner portal](https://connect.redhat.com/partner-admin/dashboard)
### [Build solutions powered by trusted partners](https://catalog.redhat.com/en/solutions)
Find solutions from our collaborative community of experts and technologies in the Red Hat® Ecosystem Catalog.
Search
### I'd like to:
- [Start a trial](https://www.redhat.com/en/products/trials)
- [Buy a learning subscription](https://www.redhat.com/en/services/training/learning-subscription/how-to-buy)
- [Manage subscriptions](https://access.redhat.com/management)
- [Contact sales](https://www.redhat.com/en/contact)
- [Contact customer service](https://www.redhat.com/en/contact/customer-service)
- [See Red Hat jobs](https://www.redhat.com/en/jobs)
### Help me find:
- [Documentation](https://docs.redhat.com/en)
- [Developer resources](https://developers.redhat.com/)
- [Tech topics](https://www.redhat.com/en/topics)
- [Architecture center](https://www.redhat.com/architect/portfolio/)
- [Security updates](https://access.redhat.com/security/security-updates/cve)
- [Customer support](https://access.redhat.com/support)
### I want to learn more about:
- [AI](https://www.redhat.com/en/topics/ai)
- [Application modernization](https://www.redhat.com/en/topics/application-modernization)
- [Automation](https://www.redhat.com/en/topics/automation)
- [Cloud-native applications](https://www.redhat.com/en/topics/cloud-native-apps)
- [Linux](https://www.redhat.com/en/topics/linux)
- [Virtualization](https://www.redhat.com/en/topics/virtualization)
[Console](https://www.redhat.com/en/hybrid-cloud-console)
[Docs](https://docs.redhat.com/en)
[Support](https://access.redhat.com/)
New For you
### Recommended
We'll recommend resources you may like as you browse. Try these suggestions for now.
- [Product trial center](https://www.redhat.com/en/products/trials)
- [Courses and exams](https://www.redhat.com/en/services/training/all-courses-exams)
- [All products](https://www.redhat.com/en/technologies/all-products)
- [Tech topics](https://www.redhat.com/en/topics)
- [Resource library](https://www.redhat.com/en/resources)
Log in
### Get more with a Red Hat account
- Console access
- Event registration
- Training & trials
- World-class support
A subscription may be required for some services.
[Log in or register](https://sso.redhat.com/)
Change page language
[Contact us](https://www.redhat.com/en/contact)
### \[\[name\]\]
[Edit avatar](https://access.redhat.com/user/edit)
Login: \[\[login\]\]
Account number: \[\[account\_number\]\]
\[\[email\]\]
Change page language
Log out
[Red Hat Blog](https://www.redhat.com/en/blog)
- [By product]()
- [Red Hat AI](https://www.redhat.com/en/blog/channel/red-hat-ai "Red Hat AI")
- [Red Hat Ansible Automation Platform](https://www.redhat.com/en/blog/channel/red-hat-ansible-automation "Red Hat Ansible Automation Platform")
- [Red Hat Enterprise Linux](https://www.redhat.com/en/blog/channel/red-hat-enterprise-linux "Red Hat Enterprise Linux")
- [Red Hat OpenShift](https://www.redhat.com/en/blog/channel/red-hat-openshift "Red Hat OpenShift")
***
[More products](https://www.redhat.com/en/blog/products "More products")
- [By topic]()
- [AI](https://www.redhat.com/en/blog/channel/artificial-intelligence "AI")
- [Virtualization](https://www.redhat.com/en/blog/channel/red-hat-virtualization "Virtualization")
- [Digital sovereignty](https://www.redhat.com/en/blog/channel/digital-sovereignty "Digital sovereignty")
- [Applications](https://www.redhat.com/en/blog/channel/applications "Applications")
- [Automation](https://www.redhat.com/en/blog/channel/management-and-automation "Automation")
- [Cloud services](https://www.redhat.com/en/blog/channel/cloud-services "Cloud services")
- [Edge computing](https://www.redhat.com/en/blog/channel/edge-computing "Edge computing")
- [Infrastructure](https://www.redhat.com/en/blog/channel/infrastructure "Infrastructure")
- [Open hybrid cloud](https://www.redhat.com/en/blog/channel/hybrid-cloud-infrastructure "Open hybrid cloud")
- [Original shows](https://www.redhat.com/en/red-hat-original-series "Original shows")
- [Security](https://www.redhat.com/en/blog/channel/security "Security")
***
[All topics](https://www.redhat.com/en/blog/channels "All topics")
- [Podcasts]()
- [Technically Speaking with Chris Wright](https://www.redhat.com/en/technically-speaking "Technically Speaking with Chris Wright")
- [Code Comments](https://www.redhat.com/en/code-comments-podcast "Code Comments")
- [Command Line Heroes](https://www.redhat.com/en/command-line-heroes "Command Line Heroes")
- [Compiler](https://www.redhat.com/en/compiler-podcast "Compiler")
- [More blogs]()
- [Red Hat Developer blog](https://developers.redhat.com/blog "Red Hat Developer blog")
- [Red Hat Partner Connect blog](https://connect.redhat.com/en/blog "Red Hat Partner Connect blog")
# Introduction to Linux Bash programming: 5 \`for\` loop tips
March 22, 2021[Nathan Lager](https://www.redhat.com/en/authors/nathan-lager "See more by Nathan Lager"), [Ricardo Gerardi](https://www.redhat.com/en/authors/rgerardi "See more by Ricardo Gerardi")*6*\-minute read
[Automation and management](https://www.redhat.com/en/blog?f[0]=taxonomy_topic_tid:27011#rhdc-search-listing)
[Linux](https://www.redhat.com/en/blog?f[0]=taxonomy_topic_tid:27061#rhdc-search-listing)
Share
Subscribe to RSS
- [Back to all posts](https://www.redhat.com/en/blog)
***
Every sysadmin probably has some skill they've learned over the years that they can point at and say, "That changed my world." That skill, or that bit of information, or that technique just changed how I do things. For many of us, that thing is *looping* in Bash. There are other approaches to automation that are certainly more robust or scalable. Most of them do not compare to the simplicity and ready usability of the `for` loop, though.
If you want to automate the configuration of thousands of systems, you should probably use Ansible. However, if you're trying to rename a thousand files, or execute the same command several times, then the `for` loop is definitely the right tool for the job.
***\[ You might also like:*** [***Mastering loops with Jinja templates in Ansible***](https://www.redhat.com/sysadmin/ansible-jinja) ***\]***
If you already have a programming or scripting background, you're probably familiar with what `for` loops do. If you're not, I'll try to break it down in plain English for you.
> The basic concept is: **FOR** a given set of items, **DO** a thing.
The given set of items can be a literal set of objects or anything that Bash can extrapolate to a list. For example, text pulled from a file, the output of another Bash command, or parameters passed via the command line. Converting this loop structure into a Bash script is also trivial. In this article, we show you some examples of how a `for` loop can make you look like a command line hero, and then we take some of those examples and put them inside a more structured Bash script.
## Basic structure of the for loop
First, let's talk about the basic structure of a `for` loop, and then we'll get into some examples.
The basic syntax of a `for` loop is:
```
for <variable name> in <a list of items>;do <some command> $<variable name>;done;
```
The **variable name** will be the variable you specify in the `do` section and will contain the item in the loop that you're on.
The **list of items** can be anything that returns a space or newline-separated list.
Here's an example:
```
$ for name in joey suzy bobby;do echo $name;done
```
That's about as simple as it gets and there isn't a whole lot going on there, but it gets you started. The variable **\$name** will contain the item in the list that the loop is currently operating on, and once the command (or commands) in the `do` section are carried out, the loop will move to the next item. You can also perform more than one action per loop. Anything between `do` and `done` will be executed. New commands just need a `;` delimiting them.
```
$ for name in joey suzy bobby; do echo first $name;echo second $name;done;
first joey
second joey
first suzy
second suzy
first bobby
second bobby
```
Now for some *real* examples.
## Renaming files
This loop takes the output of the Bash command `ls *.pdf` and performs an action on each returned file name. In this case, we're adding today's date to the end of the file name (but before the file extension).
```
for i in $(ls *.pdf); do
mv $i $(basename $i .pdf)_$(date +%Y%m%d).pdf
done
```
To illustrate, run this loop in a directory containing these files:
```
file1.pdf
file2.pdf
...
fileN.pdf
```
The files will be renamed like this:
```
file1_20210210.pdf
file2_20210210.pdf
...
fileN_20210210.pdf
```
In a directory with hundreds of files, this loop saves you a considerable amount of time in renaming all of them.
## Extrapolating lists of items
Imagine that you have a file that you want to `scp` to several servers. Remember that you can combine the `for` loop with other Bash features, such as shell expansion, which allows Bash to expand a list of items that are in a series. This can work for letters and numbers. For example:
```
$ echo {0..10}
0 1 2 3 4 5 6 7 8 9 10
```
Assuming your servers are named in some sort of pattern like, **web0**, **web1**, **web2**, **web3**, you can have Bash iterate the series of numbers like this:
```
$ for i in web{0..10};do scp somefile.txt ${i}:;done;
```
This will iterate through **web0**, **web1**, **web2**, **web3**, and so forth, executing your command on each item.
You can also define a few iterations. For example:
```
$ for i in web{0..10} db{0..2} balance_{a..c};do echo $i;done
web0
web1
web2
web3
web4
web5
web6
web7
web8
web9
web10
db0
db1
db2
balance_a
balance_b
balance_c
```
You can also combine iterations. Imagine that you have two data centers, one in the United States, another in Canada, and the server's naming convention identifies which data center a server HA pair lived in. For example, **web-us-0** would be the first web server in the US data center, while **web-ca-0** would be **web 0's** counterpart in the CA data center. To execute something on both systems, you can use a sequence like this:
```
$ for i in web-{us,ca}-{0..3};do echo $i;done
web-us-0
web-us-1
web-us-2
web-us-3
web-ca-0
web-ca-1
web-ca-2
web-ca-3
```
In case your server names are not easy to iterate through, you can provide a list of names to the `for` loop:
```
$ cat somelist
first_item
middle_things
foo
bar
baz
last_item
$ for i in `cat somelist`;do echo "ITEM: $i";done
ITEM: first_item
ITEM: middle_things
ITEM: foo
ITEM: bar
ITEM: baz
ITEM: last_item
```
## Nesting
You can also combine some of these ideas for more complex use cases. For example, imagine that you want to copy a list of files to your web servers that follow the numbered naming convention you used in the previous example.
You can accomplish that by iterating a second list based on your first list through nested loops. This gets a little hard to follow when you're doing it as a one-liner, but it can definitely be done. Your nested `for` loop gets executed on every iteration of the parent `for` loop. Be sure to specify different variable names for each loop.
To copy the list of files **file1.txt, file2.txt,** and **file3.txt** to the web servers, use this nested loop:
```
$ for i in file{1..3};do for x in web{0..3};do echo "Copying $i to server $x"; scp $i $x; done; done
Copying file1 to server web0
Copying file1 to server web1
Copying file1 to server web2
Copying file1 to server web3
Copying file2 to server web0
Copying file2 to server web1
Copying file2 to server web2
Copying file2 to server web3
Copying file3 to server web0
Copying file3 to server web1
Copying file3 to server web2
Copying file3 to server web3
```
## More creative renaming
There might be other ways to get this done, but remember, this is just an example of things you *can* do with a `for` loop. What if you have a mountain of files named something like **FILE002.txt**, and you want to replace **FILE** with something like **TEXT**. Remember that in addition to Bash itself, you also have other open source tools at your disposal, like `sed`, `grep`, and more. You can combine those tools with the `for` loop, like this:
```
$ ls FILE*.txt
FILE0.txt FILE10.txt FILE1.txt FILE2.txt FILE3.txt FILE4.txt FILE5.txt FILE6.txt FILE7.txt FILE8.txt FILE9.txt
$ for i in $(ls FILE*.txt);do mv $i `echo $i | sed s/FILE/TEXT/`;done
$ ls FILE*.txt
ls: cannot access 'FILE*.txt': No such file or directory
$ ls TEXT*.txt
TEXT0.txt TEXT10.txt TEXT1.txt TEXT2.txt TEXT3.txt TEXT4.txt TEXT5.txt TEXT6.txt TEXT7.txt TEXT8.txt TEXT9.txt
```
## Adding a for loop to a Bash script
Running `for` loops directly on the command line is great and saves you a considerable amount of time for some tasks. In addition, you can include `for` loops as part of your Bash scripts for increased power, readability, and flexibility.
For example, you can add the nested loop example to a Bash script to improve its readability, like this:
```
$ vim copy_web_files.sh
# !/bin/bash
for i in file{1..3};do
for x in web{0..3};do
echo "Copying $i to server $x"
scp $i $x
done
done
```
When you save and execute this script, the result is the same as running the nested loop example above, but it's more readable, plus it's easier to change and maintain.
```
$ bash copy_web_files.sh
Copying file1 to server web0
Copying file1 to server web1
... TRUNCATED ...
Copying file3 to server web3
```
You can also increase the flexibility and reusability of your `for` loops by including them in Bash scripts that allow parameter input. For example, to rename files like the example **More creative renaming** above allowing the user to specify the name suffix, use this script:
```
$ vim rename_files.sh
# !/bin/bash
source_prefix=$1
suffix=$2
destination_prefix=$3
for i in $(ls ${source_prefix}*.${suffix});do
mv $i $(echo $i | sed s/${source_prefix}/${destination_prefix}/)
done
```
In this script, the user provides the source file's prefix as the first parameter, the file suffix as the second, and the new prefix as the third parameter. For example, to rename all files starting with **FILE**, of type **.txt** to **TEXT**, execute the script like this :
```
$ ls FILE*.txt
FILE0.txt FILE10.txt FILE1.txt FILE2.txt FILE3.txt FILE4.txt FILE5.txt FILE6.txt FILE7.txt FILE8.txt FILE9.txt
$ bash rename_files.sh FILE txt TEXT
$ ls TEXT*.txt
TEXT0.txt TEXT10.txt TEXT1.txt TEXT2.txt TEXT3.txt TEXT4.txt TEXT5.txt TEXT6.txt TEXT7.txt TEXT8.txt TEXT9.txt
```
This is similar to the original example, but now your users can specify other parameters to change the script behavior. For example, to rename all files now starting with **TEXT** to **NEW**, use the following:
```
$ bash rename_files.sh TEXT txt NEW
$ ls NEW*.txt
NEW0.txt NEW10.txt NEW1.txt NEW2.txt NEW3.txt NEW4.txt NEW5.txt NEW6.txt NEW7.txt NEW8.txt NEW9.txt
```
***\[ A free course for you: Virtualization and Infrastructure Migration Technical Overview. \]***
## Conclusion
Hopefully, these examples have demonstrated the power of a `for` loop at the Bash command line. You really can save a lot of time and perform tasks in a less error-prone way with loops. Just be careful. Your loops will do what you ask them to, even if you ask them to do something destructive by accident, like creating (or deleting) logical volumes or virtual disks.
We hope that Bash `for` loops change your world the same way they changed ours.
***
### About the authors
[](https://www.redhat.com/en/authors/nathan-lager)
[Nathan Lager](https://www.redhat.com/en/authors/nathan-lager)
Nate is a Technical Account Manager with Red Hat and an experienced sysadmin with 20 years in the industry. He first encountered Linux (Red Hat 5.0) as a teenager, after deciding that software licensing was too expensive for a kid with no income, in the late 90’s. Since then he’s run everything from BBS’s (remember those?) to derby hat’s containing raspberry pi’s, to Linux systems in his basement, or in enterprise-class data-centers.
He runs his own blog at [undrground.org](https://www.undrground.org/), hosts the [Iron Sysadmin Podcast](https://www.ironsysadmin.com/), and when he’s not at a command line, he’s probably in the garage tinkering on his Jeep, or out on the trails.
[Read full bio](https://www.redhat.com/en/authors/nathan-lager)
[](https://www.redhat.com/en/authors/rgerardi)
[Ricardo GerardiPrincipal Consultant & Author](https://www.redhat.com/en/authors/rgerardi)
Ricardo Gerardi is a Principal Consultant at Red Hat, having transitioned from his previous role as a Technical Community Advocate for Enable Sysadmin. He's been at Red Hat since 2018, specializing in IT automation using Ansible and OpenShift.
With over 25 years of industry experience and 20+ years as a Linux and open source enthusiast and contributor, Ricardo is passionate about technology. He is particularly interested in hacking with the Go programming language and is the author of Powerful Command-Line Applications in Go and Automate Your Home Using Go. Ricardo also writes regularly for Red Hat and other blogs, covering topics like Linux, Vim, Ansible, Containers, Kubernetes, and command-line applications.
Outside of work, Ricardo enjoys spending time with his daughters, reading science fiction books, and playing video games.
[Read full bio](https://www.redhat.com/en/authors/rgerardi)
## More like this
Blog post
### [Strategic momentum: The new era of Red Hat and HPE Juniper network automation](https://www.redhat.com/en/blog/strategic-momentum-new-era-red-hat-and-hpe-juniper-network-automation)
Blog post
### [Redefining automation governance: From execution to observability at Bradesco](https://www.redhat.com/en/blog/redefining-automation-governance-execution-observability-bradesco)
Original podcast
### [Technically Speaking \| Taming AI agents with observability](https://www.redhat.com/en/technically-speaking/taming-ai-agents-observability)
Original podcast
### [Ready To Launch \| Compiler](https://www.redhat.com/en/compiler-podcast/ready-to-launch)
## Browse by channel
[Explore all channels](https://www.redhat.com/en/blog/channels "Explore all channels")

### [Automation](https://www.redhat.com/en/blog/channel/management-and-automation)
The latest on IT automation for tech, teams, and environments

### [Artificial intelligence](https://www.redhat.com/en/blog/channel/artificial-intelligence)
Updates on the platforms that free customers to run AI workloads anywhere

### [Open hybrid cloud](https://www.redhat.com/en/blog/channel/hybrid-cloud-infrastructure)
Explore how we build a more flexible future with hybrid cloud

### [Security](https://www.redhat.com/en/blog/channel/security)
The latest on how we reduce risks across environments and technologies

### [Edge computing](https://www.redhat.com/en/blog/channel/edge-computing)
Updates on the platforms that simplify operations at the edge

### [Infrastructure](https://www.redhat.com/en/blog/channel/infrastructure)
The latest on the world’s leading enterprise Linux platform

### [Applications](https://www.redhat.com/en/blog/channel/applications)
Inside our solutions to the toughest application challenges

### [Virtualization](https://www.redhat.com/en/blog/channel/red-hat-virtualization)
The future of enterprise virtualization for your workloads on-premise or across clouds
[](https://www.redhat.com/en)
[LinkedIn](https://www.linkedin.com/company/red-hat)
[YouTube](https://www.youtube.com/user/RedHatVideos)
[Facebook](https://www.facebook.com/RedHat/)
[X](https://twitter.com/RedHat)
### Platforms
- [Red Hat AI](https://www.redhat.com/en/products/ai)
- [Red Hat Enterprise Linux](https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux)
- [Red Hat OpenShift](https://www.redhat.com/en/technologies/cloud-computing/openshift)
- [Red Hat Ansible Automation Platform](https://www.redhat.com/en/technologies/management/ansible)
- [See all products](https://www.redhat.com/en/technologies/all-products)
### Tools
- [Training and certification](https://www.redhat.com/en/services/training-and-certification)
- [My account](https://www.redhat.com/wapps/ugc/protected/personalInfo.html)
- [Customer support](https://access.redhat.com/)
- [Developer resources](https://developers.redhat.com/)
- [Find a partner](https://catalog.redhat.com/partners)
- [Red Hat Ecosystem Catalog](https://catalog.redhat.com/)
- [Documentation](https://docs.redhat.com/en)
### Try, buy, & sell
- [Product trial center](https://www.redhat.com/en/products/trials)
- [Red Hat Store](https://www.redhat.com/en/store)
- [Buy online (Japan)](https://www.redhat.com/en/about/japan-buy)
- [Console](https://www.redhat.com/en/hybrid-cloud-console)
### Communicate
- [Contact sales](https://www.redhat.com/en/contact/sales)
- [Contact customer service](https://www.redhat.com/en/contact/customer-service)
- [Contact training](https://www.redhat.com/en/services/training-and-certification/contact-us)
- [Social](https://www.redhat.com/en/about/social)
### About Red Hat
Red Hat is an open hybrid cloud technology leader, delivering a consistent, comprehensive foundation for transformative IT and artificial intelligence (AI) applications in the enterprise. As a [trusted adviser to the Fortune 500](https://www.redhat.com/en/about/company), Red Hat offers cloud, developer, Linux, automation, and application platform technologies, as well as [award-winning](https://access.redhat.com/recognition) services.
- [Our company](https://www.redhat.com/en/about/company)
- [How we work](https://www.redhat.com/en/about/our-culture)
- [Customer success stories](https://www.redhat.com/en/success-stories)
- [Analyst relations](https://www.redhat.com/en/about/analysts)
- [Newsroom](https://www.redhat.com/en/about/newsroom)
- [Open source commitments](https://www.redhat.com/en/about/open-source)
- [Our social impact](https://www.redhat.com/en/about/community-social-responsibility)
- [Jobs](https://www.redhat.com/en/jobs)
### Change page language
### Red Hat legal and privacy links
- [About Red Hat](https://www.redhat.com/en/about/company)
- [Jobs](https://www.redhat.com/en/jobs)
- [Events](https://www.redhat.com/en/events)
- [Locations](https://www.redhat.com/en/about/office-locations)
- [Contact Red Hat](https://www.redhat.com/en/contact)
- [Red Hat Blog](https://www.redhat.com/en/blog)
- [Inclusion at Red Hat](https://www.redhat.com/en/about/our-culture/inclusion)
- [Cool Stuff Store](https://coolstuff.redhat.com/)
- [Red Hat Summit](https://www.redhat.com/en/summit)
© 2026 Red Hat
### Red Hat legal and privacy links
- [Privacy statement](https://www.redhat.com/en/about/privacy-policy)
- [Terms of use](https://www.redhat.com/en/about/terms-use)
- [All policies and guidelines](https://www.redhat.com/en/about/all-policies-guidelines)
- [Digital accessibility](https://www.redhat.com/en/about/digital-accessibility) |
| Readable Markdown | Every sysadmin probably has some skill they've learned over the years that they can point at and say, "That changed my world." That skill, or that bit of information, or that technique just changed how I do things. For many of us, that thing is *looping* in Bash. There are other approaches to automation that are certainly more robust or scalable. Most of them do not compare to the simplicity and ready usability of the `for` loop, though.
If you want to automate the configuration of thousands of systems, you should probably use Ansible. However, if you're trying to rename a thousand files, or execute the same command several times, then the `for` loop is definitely the right tool for the job.
***\[ You might also like:*** [***Mastering loops with Jinja templates in Ansible***](https://www.redhat.com/sysadmin/ansible-jinja) ***\]***
If you already have a programming or scripting background, you're probably familiar with what `for` loops do. If you're not, I'll try to break it down in plain English for you.
> The basic concept is: **FOR** a given set of items, **DO** a thing.
The given set of items can be a literal set of objects or anything that Bash can extrapolate to a list. For example, text pulled from a file, the output of another Bash command, or parameters passed via the command line. Converting this loop structure into a Bash script is also trivial. In this article, we show you some examples of how a `for` loop can make you look like a command line hero, and then we take some of those examples and put them inside a more structured Bash script.
## Basic structure of the for loop
First, let's talk about the basic structure of a `for` loop, and then we'll get into some examples.
The basic syntax of a `for` loop is:
```
for <variable name> in <a list of items>;do <some command> $<variable name>;done;
```
The **variable name** will be the variable you specify in the `do` section and will contain the item in the loop that you're on.
The **list of items** can be anything that returns a space or newline-separated list.
Here's an example:
```
$ for name in joey suzy bobby;do echo $name;done
```
That's about as simple as it gets and there isn't a whole lot going on there, but it gets you started. The variable **\$name** will contain the item in the list that the loop is currently operating on, and once the command (or commands) in the `do` section are carried out, the loop will move to the next item. You can also perform more than one action per loop. Anything between `do` and `done` will be executed. New commands just need a `;` delimiting them.
```
$ for name in joey suzy bobby; do echo first $name;echo second $name;done;
first joey
second joey
first suzy
second suzy
first bobby
second bobby
```
Now for some *real* examples.
## Renaming files
This loop takes the output of the Bash command `ls *.pdf` and performs an action on each returned file name. In this case, we're adding today's date to the end of the file name (but before the file extension).
```
for i in $(ls *.pdf); do
mv $i $(basename $i .pdf)_$(date +%Y%m%d).pdf
done
```
To illustrate, run this loop in a directory containing these files:
```
file1.pdf
file2.pdf
...
fileN.pdf
```
The files will be renamed like this:
```
file1_20210210.pdf
file2_20210210.pdf
...
fileN_20210210.pdf
```
In a directory with hundreds of files, this loop saves you a considerable amount of time in renaming all of them.
## Extrapolating lists of items
Imagine that you have a file that you want to `scp` to several servers. Remember that you can combine the `for` loop with other Bash features, such as shell expansion, which allows Bash to expand a list of items that are in a series. This can work for letters and numbers. For example:
```
$ echo {0..10}
0 1 2 3 4 5 6 7 8 9 10
```
Assuming your servers are named in some sort of pattern like, **web0**, **web1**, **web2**, **web3**, you can have Bash iterate the series of numbers like this:
```
$ for i in web{0..10};do scp somefile.txt ${i}:;done;
```
This will iterate through **web0**, **web1**, **web2**, **web3**, and so forth, executing your command on each item.
You can also define a few iterations. For example:
```
$ for i in web{0..10} db{0..2} balance_{a..c};do echo $i;done
web0
web1
web2
web3
web4
web5
web6
web7
web8
web9
web10
db0
db1
db2
balance_a
balance_b
balance_c
```
You can also combine iterations. Imagine that you have two data centers, one in the United States, another in Canada, and the server's naming convention identifies which data center a server HA pair lived in. For example, **web-us-0** would be the first web server in the US data center, while **web-ca-0** would be **web 0's** counterpart in the CA data center. To execute something on both systems, you can use a sequence like this:
```
$ for i in web-{us,ca}-{0..3};do echo $i;done
web-us-0
web-us-1
web-us-2
web-us-3
web-ca-0
web-ca-1
web-ca-2
web-ca-3
```
In case your server names are not easy to iterate through, you can provide a list of names to the `for` loop:
```
$ cat somelist
first_item
middle_things
foo
bar
baz
last_item
$ for i in `cat somelist`;do echo "ITEM: $i";done
ITEM: first_item
ITEM: middle_things
ITEM: foo
ITEM: bar
ITEM: baz
ITEM: last_item
```
## Nesting
You can also combine some of these ideas for more complex use cases. For example, imagine that you want to copy a list of files to your web servers that follow the numbered naming convention you used in the previous example.
You can accomplish that by iterating a second list based on your first list through nested loops. This gets a little hard to follow when you're doing it as a one-liner, but it can definitely be done. Your nested `for` loop gets executed on every iteration of the parent `for` loop. Be sure to specify different variable names for each loop.
To copy the list of files **file1.txt, file2.txt,** and **file3.txt** to the web servers, use this nested loop:
```
$ for i in file{1..3};do for x in web{0..3};do echo "Copying $i to server $x"; scp $i $x; done; done
Copying file1 to server web0
Copying file1 to server web1
Copying file1 to server web2
Copying file1 to server web3
Copying file2 to server web0
Copying file2 to server web1
Copying file2 to server web2
Copying file2 to server web3
Copying file3 to server web0
Copying file3 to server web1
Copying file3 to server web2
Copying file3 to server web3
```
## More creative renaming
There might be other ways to get this done, but remember, this is just an example of things you *can* do with a `for` loop. What if you have a mountain of files named something like **FILE002.txt**, and you want to replace **FILE** with something like **TEXT**. Remember that in addition to Bash itself, you also have other open source tools at your disposal, like `sed`, `grep`, and more. You can combine those tools with the `for` loop, like this:
```
$ ls FILE*.txt
FILE0.txt FILE10.txt FILE1.txt FILE2.txt FILE3.txt FILE4.txt FILE5.txt FILE6.txt FILE7.txt FILE8.txt FILE9.txt
$ for i in $(ls FILE*.txt);do mv $i `echo $i | sed s/FILE/TEXT/`;done
$ ls FILE*.txt
ls: cannot access 'FILE*.txt': No such file or directory
$ ls TEXT*.txt
TEXT0.txt TEXT10.txt TEXT1.txt TEXT2.txt TEXT3.txt TEXT4.txt TEXT5.txt TEXT6.txt TEXT7.txt TEXT8.txt TEXT9.txt
```
## Adding a for loop to a Bash script
Running `for` loops directly on the command line is great and saves you a considerable amount of time for some tasks. In addition, you can include `for` loops as part of your Bash scripts for increased power, readability, and flexibility.
For example, you can add the nested loop example to a Bash script to improve its readability, like this:
```
$ vim copy_web_files.sh
# !/bin/bash
for i in file{1..3};do
for x in web{0..3};do
echo "Copying $i to server $x"
scp $i $x
done
done
```
When you save and execute this script, the result is the same as running the nested loop example above, but it's more readable, plus it's easier to change and maintain.
```
$ bash copy_web_files.sh
Copying file1 to server web0
Copying file1 to server web1
... TRUNCATED ...
Copying file3 to server web3
```
You can also increase the flexibility and reusability of your `for` loops by including them in Bash scripts that allow parameter input. For example, to rename files like the example **More creative renaming** above allowing the user to specify the name suffix, use this script:
```
$ vim rename_files.sh
# !/bin/bash
source_prefix=$1
suffix=$2
destination_prefix=$3
for i in $(ls ${source_prefix}*.${suffix});do
mv $i $(echo $i | sed s/${source_prefix}/${destination_prefix}/)
done
```
In this script, the user provides the source file's prefix as the first parameter, the file suffix as the second, and the new prefix as the third parameter. For example, to rename all files starting with **FILE**, of type **.txt** to **TEXT**, execute the script like this :
```
$ ls FILE*.txt
FILE0.txt FILE10.txt FILE1.txt FILE2.txt FILE3.txt FILE4.txt FILE5.txt FILE6.txt FILE7.txt FILE8.txt FILE9.txt
$ bash rename_files.sh FILE txt TEXT
$ ls TEXT*.txt
TEXT0.txt TEXT10.txt TEXT1.txt TEXT2.txt TEXT3.txt TEXT4.txt TEXT5.txt TEXT6.txt TEXT7.txt TEXT8.txt TEXT9.txt
```
This is similar to the original example, but now your users can specify other parameters to change the script behavior. For example, to rename all files now starting with **TEXT** to **NEW**, use the following:
```
$ bash rename_files.sh TEXT txt NEW
$ ls NEW*.txt
NEW0.txt NEW10.txt NEW1.txt NEW2.txt NEW3.txt NEW4.txt NEW5.txt NEW6.txt NEW7.txt NEW8.txt NEW9.txt
```
***\[ A free course for you: Virtualization and Infrastructure Migration Technical Overview. \]***
## Conclusion
Hopefully, these examples have demonstrated the power of a `for` loop at the Bash command line. You really can save a lot of time and perform tasks in a less error-prone way with loops. Just be careful. Your loops will do what you ask them to, even if you ask them to do something destructive by accident, like creating (or deleting) logical volumes or virtual disks.
We hope that Bash `for` loops change your world the same way they changed ours. |
| Shard | 14 (laksa) |
| Root Hash | 4780968593380432814 |
| Unparsed URL | com,redhat!www,/en/blog/bash-scripting-loops s443 |