Last active
August 15, 2022 15:57
-
-
Save onlyforbopi/1eb70bbf2fb9e686f4e5d597773232cd to your computer and use it in GitHub Desktop.
Linux.Bash.Loops #linux #bash #loop #loops #for #while #iteration 1. While with multiple conditions
2. For Loop + Examples
3. While Loop + Examples
4. Until Loop + Examples
5. Loop Break + Examples
6. Loop Continue + Examples
7. Select statement + E
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Make a backup set of files | |
for value in $1/* | |
do | |
used=$( df $1 | tail -1 | awk '{ print $5 }' | sed 's/%//' ) | |
if [ $used -gt 90 ] | |
then | |
echo Low disk space 1>&2 | |
break | |
fi | |
cp $value $1/backup/ | |
done |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
for i in $( ls ); do | |
echo item: $i | |
done | |
#!/bin/bash | |
# Basic for loop | |
names='Stan Kyle Cartman' | |
for name in $names | |
do | |
echo $name | |
done | |
echo All done | |
#!/bin/bash | |
# Basic range in for loop | |
for value in {1..5} | |
do | |
echo $value | |
done | |
echo All done | |
#!/bin/bash | |
# Basic range with steps for loop | |
for value in {10..0..2} | |
do | |
echo $value | |
done | |
echo All done | |
#!/bin/bash | |
# Make a php copy of any html files | |
for value in $1/*.html | |
do | |
cp $value $1/$( basename -s .html $value ).php | |
done |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Make a php copy of any html files | |
for value in $1/*.html | |
do | |
cp $value $1/$( basename -s .html $value ).php | |
done |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
To Iterate Through Array Values | |
Use for loop syntax as follows: | |
for i in "${arrayName[@]}" | |
do | |
: | |
# do whatever on $i | |
done | |
$i will hold each item in an array. Here is a sample working script: | |
#!/bin/bash | |
# declare an array called array and define 3 vales | |
array=( one two three ) | |
for i in "${array[@]}" | |
do | |
echo $i | |
done |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
while read p; do | |
echo "$p" | |
done <peptides.txt | |
######## | |
while IFS="" read -r p || [ -n "$p" ] | |
do | |
printf '%s\n' "$p" | |
done < peptides.txt | |
######## | |
while read -u 10 p; do | |
... | |
done 10<peptides.txt | |
######## | |
cat peptides.txt | while read line | |
do | |
# do something with $line here | |
done | |
######## | |
#!/bin/bash | |
filename='peptides.txt' | |
echo Start | |
while read p; do | |
echo $p | |
done < $filename | |
########## | |
#!/bin/bash | |
filename='peptides.txt' | |
exec 4<$filename | |
echo Start | |
while read -u4 p ; do | |
echo $p | |
done | |
########## | |
#!/bin/bash | |
while IFS='' read -r line || [[ -n "$line" ]]; do | |
echo "$line" | |
done < "$1" | |
########## | |
#!/bin/bash | |
# | |
# Change the file name from "test" to desired input file | |
# (The comments in bash are prefixed with #'s) | |
for x in $(cat test.txt) | |
do | |
echo $x | |
done | |
########## | |
Option 2: For loop: Read file into single variable and parse. | |
This syntax will parse "lines" based on any white space between the tokens. This still works because the given input file lines are single-word tokens. If there were more than one token per line, then this method would not work. Also, reading the full file into a single variable is not a good strategy for large files. | |
#!/bin/bash | |
filename='peptides.txt' | |
filelines=`cat $filename` | |
echo Start | |
for line in $filelines ; do | |
echo $line | |
done | |
########### | |
for word in $(cat peptides.txt); do echo $word; done | |
### | |
for word in $(cat peptides.txt); do cmd_a.sh $word; cmd_b.py $word; done | |
##### | |
for word in $(cat peptides.txt); do cmd_a.sh $word; cmd_b.py $word; done > outfile.txt | |
##### | |
while IFS= read -r line; do | |
echo "$line" | |
done <file | |
##### | |
# delimited file | |
# ':' is the delimiter here, and there are three fields on each line in the file | |
# IFS set below is restricted to the context of `read`, it doesn't affect any other code | |
while IFS=: read -r field1 field2 field3; do | |
# process the fields | |
# if the line has less than three fields, the missing fields will be set to an empty string | |
# if the line has more than three fields, `field3` will get all the values, including the third field plus the delimiter(s) | |
done < input.txt | |
###### | |
# iterating over output of another command | |
Reading from the output of another command, using process substitution | |
while read -r line; do | |
# process the line | |
done < <(command ...) | |
###### | |
# reading from null delimited input | |
while read -r -d '' line; do | |
# logic | |
# use a second 'read ... <<< "$line"' if we need to tokenize the line | |
done < <(find /path/to/dir -print0) | |
####### | |
# reading from more than one file at a time | |
while read -u 3 -r line1 && read -u 4 -r line2; do | |
# process the lines | |
# note that the loop will end when we reach EOF on either of the files, because of the `&&` | |
done 3< input1.txt 4< input2.txt | |
######### | |
# reading entire file into array | |
while read -r line; do | |
my_array+=("$line") | |
done < my_file | |
If the file ends with an incomplete line (newline missing at the end), then: | |
while read -r line || [[ $line ]]; do | |
my_array+=("$line") | |
done < my_file | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
for filename in /Data/*.txt; do | |
for ((i=0; i<=3; i++)); do | |
./MyProgram.exe "$filename" "Logs/$(basename "$filename" .txt)_Log$i.txt" | |
done | |
done | |
##### | |
#!/bin/bash | |
for filename in $(find /Data/*.txt 2> /dev/null); do | |
for ((i=0; i<=3; i++)); do | |
./MyProgram.exe "$filename" "Logs/$(basename "$filename" .txt)_Log$i.txt" | |
done | |
done | |
##### | |
for f in file1 file2 file3 file5 | |
do | |
echo "Processing $f" | |
# do something on $f | |
done | |
##### | |
FILES="file1 | |
/path/to/file2 | |
/etc/resolv.conf" | |
for f in $FILES | |
do | |
echo "Processing $f" | |
done | |
You can loop through all files such as *.c, enter: | |
$ for f in *.c; do echo "Processing $f file.."; done | |
###### | |
#!/bin/bash | |
FILES=/path/to/* | |
for f in $FILES | |
do | |
echo "Processing $f file..." | |
# take action on each file. $f store current file name | |
cat $f | |
###### | |
#!/bin/bash | |
while IFS= read -r file | |
do | |
[ -f "$file" ] && rm -f "$file" | |
done < "/tmp/data.txt" | |
###### | |
#!/bin/bash | |
_LIGHTTPD_ETC_DEL_CHROOT_FILES="/usr/local/nixcraft/conf/apache/secure/db/dir.etc.list" | |
secureEtcDir(){ | |
local d="$1" | |
local _d="/jails/apache/$d/etc" | |
local __d="" | |
[ -f "$_LIGHTTPD_ETC_DEL_CHROOT_FILES" ] || { echo "Warning: $_LIGHTTPD_ETC_DEL_CHROOT_FILES file not found. Cannot secure files in jail etc directory."; return; } | |
echo "* Cleaning etc FILES at: \"$_d\" ..." | |
while IFS= read -r file | |
do | |
__d="$_d/$file" | |
[ -f "$__d" ] && rm -f "$__d" | |
done < "$_LIGHTTPD_ETC_DEL_CHROOT_FILES" | |
} | |
secureEtcDir "nixcraft.net.in" | |
####### | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The keys are accessed using an exclamation point: ${!array[@]}, the values are accessed using ${array[@]}. | |
You can iterate over the key/value pairs like this: | |
for i in "${!array[@]}" | |
do | |
echo "key : $i" | |
echo "value: ${array[$i]}" | |
done | |
##### | |
you can access the keys with ${!array[@]}: | |
bash-4.0$ echo "${!array[@]}" | |
foo bar | |
Then, iterating over the key/value pairs is easy: | |
for i in "${!array[@]}" | |
do | |
echo "key :" $i | |
echo "value:" ${array[$i]} | |
done | |
####### | |
accepted | |
The keys are accessed using an exclamation point: ${!array[@]}, the values are accessed using ${array[@]}. | |
You can iterate over the key/value pairs like this: | |
for i in "${!array[@]}" | |
do | |
echo "key : $i" | |
echo "value: ${array[$i]}" | |
done | |
####### | |
declare -a arr | |
echo "-------------------------------------" | |
echo "Here another example with arr numeric" | |
echo "-------------------------------------" | |
arr=( 10 200 3000 40000 500000 60 700 8000 90000 100000 ) | |
echo -e "\n Elements in arr are:\n ${arr[0]} \n ${arr[1]} \n ${arr[2]} \n ${arr[3]} \n ${arr[4]} \n ${arr[5]} \n ${arr[6]} \n ${arr[7]} \n ${arr[8]} \n ${arr[9]}" | |
echo -e " \n Total elements in arr are : ${arr[*]} \n" | |
echo -e " \n Total lenght of arr is : ${#arr[@]} \n" | |
for (( i=0; i<10; i++ )) | |
do echo "The value in position $i for arr is [ ${arr[i]} ]" | |
done | |
for (( j=0; j<10; j++ )) | |
do echo "The length in element $j is ${#arr[j]}" | |
done | |
for z in "${!arr[@]}" | |
do echo "The key ID is $z" | |
done | |
~ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
foo=string | |
for (( i=0; i<${#foo}; i++ )); do | |
echo "${foo:$i:1}" | |
done | |
###### | |
while read -n1 character; do | |
echo "$character" | |
done < <(echo -n "$words") | |
Note the use of echo -n to avoid the extraneous newline at the end. printf is another good option and may be more suitable for your particular needs. If you want to ignore whitespace then replace "$words" with "${words// /}". | |
Another option is fold. Please note however that it should never be fed into a for loop. Rather, use a while loop as follows: | |
while read char; do | |
echo "$char" | |
done < <(fold -w1 <<<"$words") | |
##### |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
for var in "$@" | |
do | |
echo "$var" | |
done | |
#### | |
#this prints all arguments | |
while test $# -gt 0 | |
do | |
echo $1 | |
shift | |
done | |
#### | |
argc=$# | |
argv=($@) | |
for (( j=0; j<argc; j++ )); do | |
echo ${argv[j]} | |
done | |
## | |
# Under development | |
aparse() { | |
while [[ $# > 0 ]] ; do | |
case "$1" in | |
--arg1) | |
varg1=${2} | |
echo $varg1 | |
shift | |
;; | |
--arg2) | |
varg2=true | |
echo $varg2 | |
;; | |
esac | |
shift | |
done | |
} | |
aparse "$@" | |
# Better version | |
#!/bin/bash | |
PARAMS="" | |
while (( "$#" )); do | |
case "$1" in | |
-f|--flag-with-argument) | |
FARG=$2 | |
shift 2 | |
;; | |
--) # end argument parsing | |
shift | |
break | |
;; | |
-*|--*=) # unsupported flags | |
echo "Error: Unsupported flag $1" >&2 | |
exit 1 | |
;; | |
*) # preserve positional arguments | |
PARAMS="$PARAMS $1" | |
shift | |
;; | |
esac | |
done | |
# set positional arguments in their proper place | |
eval set -- "$PARAMS" | |
There’s a lot going on here so let’s break it down. First we set a variable `PARAMS` to save any positional arguments into for later. Next, we create a while loop that evaluates the length of the arguments array and exits when it reaches zero. Inside of the while loop, pass the first element in the arguments array through a case statement looking for either a custom flag or some default flag patterns. If the statement matches a flag, we do something (like the save the value to a variable) and we use the `shift` statement to pop elements off the front of the arguments array before the next iteration of the loop. If the statement matches a regular argument, we save it into a string to be evaluated later. Finally, after all the arguments have been processed, we set the arguments array to the list of positional arguments we saved using the `set` command. | |
############################### | |
# for i | |
107 | |
down vote | |
Note that Robert's answer is correct, and it works in sh as well. You can (portably) simplify it even further: | |
for i in "$@" | |
is equivalent to: | |
for i | |
I.e., you don't need anything! | |
Testing ($ is command prompt): | |
$ set a b "spaces here" d | |
$ for i; do echo "$i"; done | |
a | |
b | |
spaces here | |
d | |
$ for i in "$@"; do echo "$i"; done | |
a | |
b | |
spaces here | |
d | |
I first read about this in Unix Programming Environment by Kernighan and Pike. | |
In bash, help for documents this: | |
for NAME [in WORDS ... ;] do COMMANDS; done | |
If 'in WORDS ...;' is not present, then 'in "$@"' is assumed. | |
####### | |
#!/bin/bash | |
# make sure you always put $f in double quotes to avoid any nasty surprises i.e. "$f" | |
for f in $* | |
do | |
echo "Processing $f file..." | |
# rm "$f" | |
done | |
OR | |
#!/bin/bash | |
# make sure you always put $f in double quotes to avoid any nasty surprises i.e. "$f" | |
for f in $@ | |
do | |
echo "Processing $f file..." | |
# rm "$f" | |
done | |
Please note that $@ expanded as “$1” “$2” “$3” … “$n” and $* expanded as “$1y$2y$3y…$n”, where y is the value of IFS variable i.e. “$*” is one long string and $IFS act as an separator or token delimiters. | |
The following example use shell variables to store actual path names and then files are processed using the for loop: | |
#!/bin/bash | |
_base="/jail/.conf" | |
_dfiles="${base}/nginx/etc/conf/*.conf" | |
for f in $_dfiles | |
do | |
lb2file="/tmp/${f##*/}.$$" #tmp file | |
sed 's/Load_Balancer-1/Load_Balancer-2/' "$f" > "${lb2file}" # update signature | |
scp "${lb2file}" [email protected]:${f} # scp updated file to lb2 | |
rm -f "${lb2file}" | |
done | |
Updated for accuracy! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# A simple menu system | |
names='Kyle Cartman Stan Quit' | |
PS3='Select character: ' | |
select name in $names | |
do | |
if [ $name == 'Quit' ] | |
then | |
break | |
fi | |
echo Hello $name | |
done | |
echo Bye |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
COUNTER=20 | |
until [ $COUNTER -lt 10 ]; do | |
echo COUNTER $COUNTER | |
let COUNTER-=1 | |
done | |
counter=1 | |
until [ $counter -gt 10 ] | |
do | |
echo $counter | |
((counter++)) | |
done | |
echo All done |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
COUNTER=0 | |
while [ $COUNTER -lt 10 ]; do | |
echo The counter is $COUNTER | |
let COUNTER=COUNTER+1 | |
done | |
#!/bin/bash | |
# Basic while loop | |
counter=1 | |
while [ $counter -le 10 ] | |
do | |
echo $counter | |
((counter++)) | |
done | |
echo All done |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Single POSIX test command with -o operator (not recommended anymore). | |
# Quotes strongly recommended to guard against empty or undefined variables. | |
while [ "$stats" -gt 300 -o "$stats" -eq 0 ] | |
# Two POSIX test commands joined in a list with ||. | |
# Quotes strongly recommended to guard against empty or undefined variables. | |
while [ "$stats" -gt 300 ] || [ "$stats" -eq 0 ] | |
# Two bash conditional expressions joined in a list with ||. | |
while [[ $stats -gt 300 ]] || [[ $stats -eq 0 ]] | |
# A single bash conditional expression with the || operator. | |
while [[ $stats -gt 300 || $stats -eq 0 ]] | |
# Two bash arithmetic expressions joined in a list with ||. | |
# $ optional, as a string can only be interpreted as a variable | |
while (( stats > 300 )) || (( stats == 0 )) | |
# And finally, a single bash arithmetic expression with the || operator. | |
# $ optional, as a string can only be interpreted as a variable | |
while (( stats > 300 || stats == 0 )) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment