Better way then having multiple elif statement
up vote
0
down vote
favorite
I have a file called file.txt which has some random numbers from 1 to 100. So a script reads the file and executes a bunch of commands and print some statements.
One way of achieving the result could be something like these but having 100 if
and elif
statement in a script doesn't look so nice.
for i in `cat file.txt`; do
echo "Displaying" $i
if [[ $i = 1 ]]; then
echo "blah blah blah for" $i
command1
command2
elif [[ $i = 2 ]]; then
echo "blah blah blah for" $i
command3
command4
command5
elif [[ $i = 3 ]]; then
echo "blah blah blah for" $i
command6
command7
elif [[ $i = 4 ]]; then
echo "blah blah blah for" $i
command8
command9
command10
elif [[ $i = 5 ]]; then
echo "blah blah blah for" $i
command11
command12
command13
command14
elif [[ $i = 6 ]]; then
echo "blah blah blah for" $i
command15
....
....
....
....
....
....
elif [[ $i = 99 ]]; then
echo "blah blah blah for" $i
command310
command311
command312
command313
command314
elif [[ $i = 100 ]]; then
echo "blah blah blah for" $i
command315
fi
done
Is there any better or smarter way to do these on bash
bash if-statement
add a comment |
up vote
0
down vote
favorite
I have a file called file.txt which has some random numbers from 1 to 100. So a script reads the file and executes a bunch of commands and print some statements.
One way of achieving the result could be something like these but having 100 if
and elif
statement in a script doesn't look so nice.
for i in `cat file.txt`; do
echo "Displaying" $i
if [[ $i = 1 ]]; then
echo "blah blah blah for" $i
command1
command2
elif [[ $i = 2 ]]; then
echo "blah blah blah for" $i
command3
command4
command5
elif [[ $i = 3 ]]; then
echo "blah blah blah for" $i
command6
command7
elif [[ $i = 4 ]]; then
echo "blah blah blah for" $i
command8
command9
command10
elif [[ $i = 5 ]]; then
echo "blah blah blah for" $i
command11
command12
command13
command14
elif [[ $i = 6 ]]; then
echo "blah blah blah for" $i
command15
....
....
....
....
....
....
elif [[ $i = 99 ]]; then
echo "blah blah blah for" $i
command310
command311
command312
command313
command314
elif [[ $i = 100 ]]; then
echo "blah blah blah for" $i
command315
fi
done
Is there any better or smarter way to do these on bash
bash if-statement
2
I'd start with acase
statementcase $i in 1) ... ;; 2) ... ;; ... ;; 99) ... ;; esac
.
– chepner
Nov 19 at 20:20
@JosephLi write comments with unicorn emojis betweenelif
s then it will look nice
– oguzismail
Nov 19 at 20:26
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I have a file called file.txt which has some random numbers from 1 to 100. So a script reads the file and executes a bunch of commands and print some statements.
One way of achieving the result could be something like these but having 100 if
and elif
statement in a script doesn't look so nice.
for i in `cat file.txt`; do
echo "Displaying" $i
if [[ $i = 1 ]]; then
echo "blah blah blah for" $i
command1
command2
elif [[ $i = 2 ]]; then
echo "blah blah blah for" $i
command3
command4
command5
elif [[ $i = 3 ]]; then
echo "blah blah blah for" $i
command6
command7
elif [[ $i = 4 ]]; then
echo "blah blah blah for" $i
command8
command9
command10
elif [[ $i = 5 ]]; then
echo "blah blah blah for" $i
command11
command12
command13
command14
elif [[ $i = 6 ]]; then
echo "blah blah blah for" $i
command15
....
....
....
....
....
....
elif [[ $i = 99 ]]; then
echo "blah blah blah for" $i
command310
command311
command312
command313
command314
elif [[ $i = 100 ]]; then
echo "blah blah blah for" $i
command315
fi
done
Is there any better or smarter way to do these on bash
bash if-statement
I have a file called file.txt which has some random numbers from 1 to 100. So a script reads the file and executes a bunch of commands and print some statements.
One way of achieving the result could be something like these but having 100 if
and elif
statement in a script doesn't look so nice.
for i in `cat file.txt`; do
echo "Displaying" $i
if [[ $i = 1 ]]; then
echo "blah blah blah for" $i
command1
command2
elif [[ $i = 2 ]]; then
echo "blah blah blah for" $i
command3
command4
command5
elif [[ $i = 3 ]]; then
echo "blah blah blah for" $i
command6
command7
elif [[ $i = 4 ]]; then
echo "blah blah blah for" $i
command8
command9
command10
elif [[ $i = 5 ]]; then
echo "blah blah blah for" $i
command11
command12
command13
command14
elif [[ $i = 6 ]]; then
echo "blah blah blah for" $i
command15
....
....
....
....
....
....
elif [[ $i = 99 ]]; then
echo "blah blah blah for" $i
command310
command311
command312
command313
command314
elif [[ $i = 100 ]]; then
echo "blah blah blah for" $i
command315
fi
done
Is there any better or smarter way to do these on bash
bash if-statement
bash if-statement
edited Nov 19 at 22:20
kvantour
7,66631129
7,66631129
asked Nov 19 at 20:16
Joseph Li
1
1
2
I'd start with acase
statementcase $i in 1) ... ;; 2) ... ;; ... ;; 99) ... ;; esac
.
– chepner
Nov 19 at 20:20
@JosephLi write comments with unicorn emojis betweenelif
s then it will look nice
– oguzismail
Nov 19 at 20:26
add a comment |
2
I'd start with acase
statementcase $i in 1) ... ;; 2) ... ;; ... ;; 99) ... ;; esac
.
– chepner
Nov 19 at 20:20
@JosephLi write comments with unicorn emojis betweenelif
s then it will look nice
– oguzismail
Nov 19 at 20:26
2
2
I'd start with a
case
statement case $i in 1) ... ;; 2) ... ;; ... ;; 99) ... ;; esac
.– chepner
Nov 19 at 20:20
I'd start with a
case
statement case $i in 1) ... ;; 2) ... ;; ... ;; 99) ... ;; esac
.– chepner
Nov 19 at 20:20
@JosephLi write comments with unicorn emojis between
elif
s then it will look nice– oguzismail
Nov 19 at 20:26
@JosephLi write comments with unicorn emojis between
elif
s then it will look nice– oguzismail
Nov 19 at 20:26
add a comment |
2 Answers
2
active
oldest
votes
up vote
2
down vote
Classic case of case
:
case "$i" in
1)
echo "blah blah blah for" $i
command1
command2
;;
[…]
*)
echo "Unhandled value $i" >&2
exit 2
esac
In addition to this:
Use awhile
loop to process lines- Use More Quotes™
add a comment |
up vote
1
down vote
My suggestion would be to make use of a case
statement. It is the bash version of what is known in programming as the switch statement. They are generally faster then an if-then-else statement as they are most likely implemented with a lookup table or hash-list.
Additionally, an optimized implementation may execute much faster than the alternative, because it is often implemented by using an indexed branch table. For example, deciding program flow based on a single character's value, if correctly implemented, is vastly more efficient than the alternative, reducing instruction path lengths considerably. When implemented as such, a switch statement essentially becomes a perfect hash.
source: Wikipedia
An interesting comparison can be found here: Which is faster of two case or if?
To address your code, you're loop of the form
for i in $(cat file); do
...
done
should be rewritten. As you read the file word-by-word, you should write something like:
while read -r line; do
for i in $line; do
...
done
done < file
You're if-then-else is then rewritten as:
case "$i" in
1) command1; command2; command3 ;;
2) command4; command5; command6 ;;
...
100) command315; command316;;
esac
1
Bash case statements are not optimised even when it is possible (and since the options are subject to parameter expansion, it may well not be possible. So they aren't much faster, but they are easier to write (and read). They are a little faster basically because they don't require the [/[[ commands to be interpreted.
– rici
Nov 19 at 22:11
@rici According to stackoverflow.com/questions/20018037/… there is a clear difference.
– kvantour
Nov 19 at 22:16
yes, but the difference is much more marked for the[
command than for the[[
builtin. It has nothing to do with lookup tables or indexed lookups.
– rici
Nov 19 at 22:33
@rici On my current system I still have a 1/3 speedup usingcase
instead of[[ ... ]]]
– kvantour
Nov 19 at 22:42
1
You mean it's 33% faster, right? A hash table would be much faster, since it wouldn't require more than one test.
– rici
Nov 19 at 22:55
|
show 1 more comment
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53381999%2fbetter-way-then-having-multiple-elif-statement%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
Classic case of case
:
case "$i" in
1)
echo "blah blah blah for" $i
command1
command2
;;
[…]
*)
echo "Unhandled value $i" >&2
exit 2
esac
In addition to this:
Use awhile
loop to process lines- Use More Quotes™
add a comment |
up vote
2
down vote
Classic case of case
:
case "$i" in
1)
echo "blah blah blah for" $i
command1
command2
;;
[…]
*)
echo "Unhandled value $i" >&2
exit 2
esac
In addition to this:
Use awhile
loop to process lines- Use More Quotes™
add a comment |
up vote
2
down vote
up vote
2
down vote
Classic case of case
:
case "$i" in
1)
echo "blah blah blah for" $i
command1
command2
;;
[…]
*)
echo "Unhandled value $i" >&2
exit 2
esac
In addition to this:
Use awhile
loop to process lines- Use More Quotes™
Classic case of case
:
case "$i" in
1)
echo "blah blah blah for" $i
command1
command2
;;
[…]
*)
echo "Unhandled value $i" >&2
exit 2
esac
In addition to this:
Use awhile
loop to process lines- Use More Quotes™
answered Nov 19 at 20:31
l0b0
33.1k1583144
33.1k1583144
add a comment |
add a comment |
up vote
1
down vote
My suggestion would be to make use of a case
statement. It is the bash version of what is known in programming as the switch statement. They are generally faster then an if-then-else statement as they are most likely implemented with a lookup table or hash-list.
Additionally, an optimized implementation may execute much faster than the alternative, because it is often implemented by using an indexed branch table. For example, deciding program flow based on a single character's value, if correctly implemented, is vastly more efficient than the alternative, reducing instruction path lengths considerably. When implemented as such, a switch statement essentially becomes a perfect hash.
source: Wikipedia
An interesting comparison can be found here: Which is faster of two case or if?
To address your code, you're loop of the form
for i in $(cat file); do
...
done
should be rewritten. As you read the file word-by-word, you should write something like:
while read -r line; do
for i in $line; do
...
done
done < file
You're if-then-else is then rewritten as:
case "$i" in
1) command1; command2; command3 ;;
2) command4; command5; command6 ;;
...
100) command315; command316;;
esac
1
Bash case statements are not optimised even when it is possible (and since the options are subject to parameter expansion, it may well not be possible. So they aren't much faster, but they are easier to write (and read). They are a little faster basically because they don't require the [/[[ commands to be interpreted.
– rici
Nov 19 at 22:11
@rici According to stackoverflow.com/questions/20018037/… there is a clear difference.
– kvantour
Nov 19 at 22:16
yes, but the difference is much more marked for the[
command than for the[[
builtin. It has nothing to do with lookup tables or indexed lookups.
– rici
Nov 19 at 22:33
@rici On my current system I still have a 1/3 speedup usingcase
instead of[[ ... ]]]
– kvantour
Nov 19 at 22:42
1
You mean it's 33% faster, right? A hash table would be much faster, since it wouldn't require more than one test.
– rici
Nov 19 at 22:55
|
show 1 more comment
up vote
1
down vote
My suggestion would be to make use of a case
statement. It is the bash version of what is known in programming as the switch statement. They are generally faster then an if-then-else statement as they are most likely implemented with a lookup table or hash-list.
Additionally, an optimized implementation may execute much faster than the alternative, because it is often implemented by using an indexed branch table. For example, deciding program flow based on a single character's value, if correctly implemented, is vastly more efficient than the alternative, reducing instruction path lengths considerably. When implemented as such, a switch statement essentially becomes a perfect hash.
source: Wikipedia
An interesting comparison can be found here: Which is faster of two case or if?
To address your code, you're loop of the form
for i in $(cat file); do
...
done
should be rewritten. As you read the file word-by-word, you should write something like:
while read -r line; do
for i in $line; do
...
done
done < file
You're if-then-else is then rewritten as:
case "$i" in
1) command1; command2; command3 ;;
2) command4; command5; command6 ;;
...
100) command315; command316;;
esac
1
Bash case statements are not optimised even when it is possible (and since the options are subject to parameter expansion, it may well not be possible. So they aren't much faster, but they are easier to write (and read). They are a little faster basically because they don't require the [/[[ commands to be interpreted.
– rici
Nov 19 at 22:11
@rici According to stackoverflow.com/questions/20018037/… there is a clear difference.
– kvantour
Nov 19 at 22:16
yes, but the difference is much more marked for the[
command than for the[[
builtin. It has nothing to do with lookup tables or indexed lookups.
– rici
Nov 19 at 22:33
@rici On my current system I still have a 1/3 speedup usingcase
instead of[[ ... ]]]
– kvantour
Nov 19 at 22:42
1
You mean it's 33% faster, right? A hash table would be much faster, since it wouldn't require more than one test.
– rici
Nov 19 at 22:55
|
show 1 more comment
up vote
1
down vote
up vote
1
down vote
My suggestion would be to make use of a case
statement. It is the bash version of what is known in programming as the switch statement. They are generally faster then an if-then-else statement as they are most likely implemented with a lookup table or hash-list.
Additionally, an optimized implementation may execute much faster than the alternative, because it is often implemented by using an indexed branch table. For example, deciding program flow based on a single character's value, if correctly implemented, is vastly more efficient than the alternative, reducing instruction path lengths considerably. When implemented as such, a switch statement essentially becomes a perfect hash.
source: Wikipedia
An interesting comparison can be found here: Which is faster of two case or if?
To address your code, you're loop of the form
for i in $(cat file); do
...
done
should be rewritten. As you read the file word-by-word, you should write something like:
while read -r line; do
for i in $line; do
...
done
done < file
You're if-then-else is then rewritten as:
case "$i" in
1) command1; command2; command3 ;;
2) command4; command5; command6 ;;
...
100) command315; command316;;
esac
My suggestion would be to make use of a case
statement. It is the bash version of what is known in programming as the switch statement. They are generally faster then an if-then-else statement as they are most likely implemented with a lookup table or hash-list.
Additionally, an optimized implementation may execute much faster than the alternative, because it is often implemented by using an indexed branch table. For example, deciding program flow based on a single character's value, if correctly implemented, is vastly more efficient than the alternative, reducing instruction path lengths considerably. When implemented as such, a switch statement essentially becomes a perfect hash.
source: Wikipedia
An interesting comparison can be found here: Which is faster of two case or if?
To address your code, you're loop of the form
for i in $(cat file); do
...
done
should be rewritten. As you read the file word-by-word, you should write something like:
while read -r line; do
for i in $line; do
...
done
done < file
You're if-then-else is then rewritten as:
case "$i" in
1) command1; command2; command3 ;;
2) command4; command5; command6 ;;
...
100) command315; command316;;
esac
edited Nov 19 at 20:44
answered Nov 19 at 20:35
kvantour
7,66631129
7,66631129
1
Bash case statements are not optimised even when it is possible (and since the options are subject to parameter expansion, it may well not be possible. So they aren't much faster, but they are easier to write (and read). They are a little faster basically because they don't require the [/[[ commands to be interpreted.
– rici
Nov 19 at 22:11
@rici According to stackoverflow.com/questions/20018037/… there is a clear difference.
– kvantour
Nov 19 at 22:16
yes, but the difference is much more marked for the[
command than for the[[
builtin. It has nothing to do with lookup tables or indexed lookups.
– rici
Nov 19 at 22:33
@rici On my current system I still have a 1/3 speedup usingcase
instead of[[ ... ]]]
– kvantour
Nov 19 at 22:42
1
You mean it's 33% faster, right? A hash table would be much faster, since it wouldn't require more than one test.
– rici
Nov 19 at 22:55
|
show 1 more comment
1
Bash case statements are not optimised even when it is possible (and since the options are subject to parameter expansion, it may well not be possible. So they aren't much faster, but they are easier to write (and read). They are a little faster basically because they don't require the [/[[ commands to be interpreted.
– rici
Nov 19 at 22:11
@rici According to stackoverflow.com/questions/20018037/… there is a clear difference.
– kvantour
Nov 19 at 22:16
yes, but the difference is much more marked for the[
command than for the[[
builtin. It has nothing to do with lookup tables or indexed lookups.
– rici
Nov 19 at 22:33
@rici On my current system I still have a 1/3 speedup usingcase
instead of[[ ... ]]]
– kvantour
Nov 19 at 22:42
1
You mean it's 33% faster, right? A hash table would be much faster, since it wouldn't require more than one test.
– rici
Nov 19 at 22:55
1
1
Bash case statements are not optimised even when it is possible (and since the options are subject to parameter expansion, it may well not be possible. So they aren't much faster, but they are easier to write (and read). They are a little faster basically because they don't require the [/[[ commands to be interpreted.
– rici
Nov 19 at 22:11
Bash case statements are not optimised even when it is possible (and since the options are subject to parameter expansion, it may well not be possible. So they aren't much faster, but they are easier to write (and read). They are a little faster basically because they don't require the [/[[ commands to be interpreted.
– rici
Nov 19 at 22:11
@rici According to stackoverflow.com/questions/20018037/… there is a clear difference.
– kvantour
Nov 19 at 22:16
@rici According to stackoverflow.com/questions/20018037/… there is a clear difference.
– kvantour
Nov 19 at 22:16
yes, but the difference is much more marked for the
[
command than for the [[
builtin. It has nothing to do with lookup tables or indexed lookups.– rici
Nov 19 at 22:33
yes, but the difference is much more marked for the
[
command than for the [[
builtin. It has nothing to do with lookup tables or indexed lookups.– rici
Nov 19 at 22:33
@rici On my current system I still have a 1/3 speedup using
case
instead of [[ ... ]]]
– kvantour
Nov 19 at 22:42
@rici On my current system I still have a 1/3 speedup using
case
instead of [[ ... ]]]
– kvantour
Nov 19 at 22:42
1
1
You mean it's 33% faster, right? A hash table would be much faster, since it wouldn't require more than one test.
– rici
Nov 19 at 22:55
You mean it's 33% faster, right? A hash table would be much faster, since it wouldn't require more than one test.
– rici
Nov 19 at 22:55
|
show 1 more comment
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53381999%2fbetter-way-then-having-multiple-elif-statement%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
I'd start with a
case
statementcase $i in 1) ... ;; 2) ... ;; ... ;; 99) ... ;; esac
.– chepner
Nov 19 at 20:20
@JosephLi write comments with unicorn emojis between
elif
s then it will look nice– oguzismail
Nov 19 at 20:26