Write a function that checks if a string starts with or contains somethingHow to pass a string parameter on bash function?Function that calls another function with list of arguments doesn't workHow do i create a function to test if the input contains any character?A basic function that doesn't workVIM: function that checks if external program is runningTerminal emulator crashes with function with nested case statements?Test if a string contains a substringCall function that call ffmpeg in loopShell: Using function with parameters in ifDetermining if the first string starts with second string
IIS LAN and WAN separate SSL certificates for the same server
Are athletes' college degrees discounted by employers and graduate school admissions?
Arcane Tradition and Cost Efficiency: Learn spells on level-up, or learn them from scrolls/spellbooks?
Does anyone recognize these rockets, and their location?
How can this shape perfectly cover a cube?
Can I give my friend the sour dough "throw away" as a starter to their sourdough starter?
What made the Ancient One do this in Endgame?
At zero velocity, is this object neither speeding up nor slowing down?
For Saintsbury, which English novelists constituted the "great quartet of the mid-eighteenth century"?
Does PC weight have a mechanical effect?
Was the Lonely Mountain, where Smaug lived, a volcano?
Is there a risk to write an invitation letter for a stranger to obtain a Czech (Schengen) visa?
Should I worry about having my credit pulled multiple times while car shopping?
Monotonic operations and integrals
How do credit card companies know what type of business I'm paying for?
How to remove multiple elements from Set/Map AND knowing which ones were removed?
Why can't we feel the Earth's revolution?
My parents claim they cannot pay for my college education; what are my options?
Why did the USA sell so many airplanes prior to WW2?
100-doors puzzle
Can artificial satellite positions affect tides?
Idiom for 'person who gets violent when drunk"
Must a CPU have a GPU if the motherboard provides a display port (when there isn't any separate video card)?
The title "Mord mit Aussicht" explained
Write a function that checks if a string starts with or contains something
How to pass a string parameter on bash function?Function that calls another function with list of arguments doesn't workHow do i create a function to test if the input contains any character?A basic function that doesn't workVIM: function that checks if external program is runningTerminal emulator crashes with function with nested case statements?Test if a string contains a substringCall function that call ffmpeg in loopShell: Using function with parameters in ifDetermining if the first string starts with second string
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I want to write a function that checks if a given variable, say, var
, starts with any of the words in a given list of strings. This list won't change.
To instantiate, let's pretend that I want to check if var
starts with aa
, abc
or 3@3
.
Moreover, I want to check if var
contains the character >
.
Let's say this function is called check_func
. My intended usage looks something like
if check_func "$var"; then
do stuff
fi
For example, it should "do stuff" foraardvark
, abcdef
, 3@3com.com
and 12>5
.
I've seen this SO question where a user provides part of the work:
beginswith() case $2 in "$1"*) true;; *) false;; esac;
My idea is that I would iterate over the list mentioned above and use this function. My difficulty lies in not understanding exactly how exiting (or whatever replaces returning) should be done to make this work.
shell string function pattern-matching
New contributor
add a comment |
I want to write a function that checks if a given variable, say, var
, starts with any of the words in a given list of strings. This list won't change.
To instantiate, let's pretend that I want to check if var
starts with aa
, abc
or 3@3
.
Moreover, I want to check if var
contains the character >
.
Let's say this function is called check_func
. My intended usage looks something like
if check_func "$var"; then
do stuff
fi
For example, it should "do stuff" foraardvark
, abcdef
, 3@3com.com
and 12>5
.
I've seen this SO question where a user provides part of the work:
beginswith() case $2 in "$1"*) true;; *) false;; esac;
My idea is that I would iterate over the list mentioned above and use this function. My difficulty lies in not understanding exactly how exiting (or whatever replaces returning) should be done to make this work.
shell string function pattern-matching
New contributor
It just occurred to me that your question is ambiguous. Do you mean (1) I want to check ifvar
starts withaa
. I want to check ifvar
starts withabc
. I want to check ifvar
starts with3@3
. And I want to check ifvar
contains>
. ? Or do you mean (2) I want to check ifvar
starts withaa
,abc
or3@3
, and it also contains>
. ?
– G-Man
Jun 7 at 21:23
@G-Man The first one. Thanks for bringing that up.
– No Imaginatition
Jun 7 at 22:44
add a comment |
I want to write a function that checks if a given variable, say, var
, starts with any of the words in a given list of strings. This list won't change.
To instantiate, let's pretend that I want to check if var
starts with aa
, abc
or 3@3
.
Moreover, I want to check if var
contains the character >
.
Let's say this function is called check_func
. My intended usage looks something like
if check_func "$var"; then
do stuff
fi
For example, it should "do stuff" foraardvark
, abcdef
, 3@3com.com
and 12>5
.
I've seen this SO question where a user provides part of the work:
beginswith() case $2 in "$1"*) true;; *) false;; esac;
My idea is that I would iterate over the list mentioned above and use this function. My difficulty lies in not understanding exactly how exiting (or whatever replaces returning) should be done to make this work.
shell string function pattern-matching
New contributor
I want to write a function that checks if a given variable, say, var
, starts with any of the words in a given list of strings. This list won't change.
To instantiate, let's pretend that I want to check if var
starts with aa
, abc
or 3@3
.
Moreover, I want to check if var
contains the character >
.
Let's say this function is called check_func
. My intended usage looks something like
if check_func "$var"; then
do stuff
fi
For example, it should "do stuff" foraardvark
, abcdef
, 3@3com.com
and 12>5
.
I've seen this SO question where a user provides part of the work:
beginswith() case $2 in "$1"*) true;; *) false;; esac;
My idea is that I would iterate over the list mentioned above and use this function. My difficulty lies in not understanding exactly how exiting (or whatever replaces returning) should be done to make this work.
shell string function pattern-matching
shell string function pattern-matching
New contributor
New contributor
edited Jun 8 at 4:27
G-Man
14.7k94175
14.7k94175
New contributor
asked Jun 7 at 19:55
No ImaginatitionNo Imaginatition
333
333
New contributor
New contributor
It just occurred to me that your question is ambiguous. Do you mean (1) I want to check ifvar
starts withaa
. I want to check ifvar
starts withabc
. I want to check ifvar
starts with3@3
. And I want to check ifvar
contains>
. ? Or do you mean (2) I want to check ifvar
starts withaa
,abc
or3@3
, and it also contains>
. ?
– G-Man
Jun 7 at 21:23
@G-Man The first one. Thanks for bringing that up.
– No Imaginatition
Jun 7 at 22:44
add a comment |
It just occurred to me that your question is ambiguous. Do you mean (1) I want to check ifvar
starts withaa
. I want to check ifvar
starts withabc
. I want to check ifvar
starts with3@3
. And I want to check ifvar
contains>
. ? Or do you mean (2) I want to check ifvar
starts withaa
,abc
or3@3
, and it also contains>
. ?
– G-Man
Jun 7 at 21:23
@G-Man The first one. Thanks for bringing that up.
– No Imaginatition
Jun 7 at 22:44
It just occurred to me that your question is ambiguous. Do you mean (1) I want to check if
var
starts with aa
. I want to check if var
starts with abc
. I want to check if var
starts with 3@3
. And I want to check if var
contains >
. ? Or do you mean (2) I want to check if var
starts with aa
, abc
or 3@3
, and it also contains >
. ?– G-Man
Jun 7 at 21:23
It just occurred to me that your question is ambiguous. Do you mean (1) I want to check if
var
starts with aa
. I want to check if var
starts with abc
. I want to check if var
starts with 3@3
. And I want to check if var
contains >
. ? Or do you mean (2) I want to check if var
starts with aa
, abc
or 3@3
, and it also contains >
. ?– G-Man
Jun 7 at 21:23
@G-Man The first one. Thanks for bringing that up.
– No Imaginatition
Jun 7 at 22:44
@G-Man The first one. Thanks for bringing that up.
– No Imaginatition
Jun 7 at 22:44
add a comment |
4 Answers
4
active
oldest
votes
check_prefixes ()
value=$1
for prefix in aa abc 3@3; do
case $value in
"$prefix"*) return 0
esac
done
return 1
check_contains_gt ()
value=$1
case $value in
*">"*) return 0
esac
return 1
var='aa>'
if check_prefixes "$var" && check_contains_gt "$var"; then
printf '"%s" contains ">" and starts with one of the prefixesn' "$var"
fi
I divided the tests up into two functions. Both use case ... esac
and returns success (zero) as soon as this can be determined. If nothing matches, failure (1) is returned.
To make the list of prefixes more of a dynamic list, one could possibly write the first function as
check_prefixes ()
value=$1
shift
for prefix do
case $value in
"$prefix"*) return 0
esac
done
return 1
(the value to inspect is the first argument, which we save in value
and then shift
off the list of arguments to the function; we then iterate over the remaining arguments) and then call it as
check_prefixes "$var" aa abc 3@3
The second function could be changed in a similar manner, into
check_contains ()
value=$1
shift
case $value in
*"$1"*) return 0
esac
return 1
(to check for some arbitrary substring), or
check_contains_oneof ()
value=$1
shift
for substring do
case $value in
*"$substring"*) return 0
esac
done
return 1
(to check for any of a number of substrings)
Thanks. My intended logic is with a logical or instead of a logical and. Should it bevalue
instead ofvar
in the first function's definition?
– No Imaginatition
Jun 7 at 23:12
@NoImaginatition OK, just change the logic in the code calling the functions (||
instead of&&
). Yes, that's a typo in my code, I'll fix it at once, thanks.
– Kusalananda♦
Jun 7 at 23:14
I'm trying to combine both functions into one by definingcheck_func()
, but it won't work forecho a >file
. Any idea why?
– No Imaginatition
Jun 7 at 23:16
@NoImaginatition Always double quote variable expansions ("$1"
) unless you know exactly in what contexts this is not needed.
– Kusalananda♦
Jun 7 at 23:19
Great, it worked. If it's not much to ask, what is it that it makes it fail without the double quotes? I tried to test if it would expand the second call of$1
, and it seems to expand. I tested it withtest () echo $1 $1;
and it worked fine.
– No Imaginatition
Jun 7 at 23:23
add a comment |
For bash:
Using the properties of regex you can write start
with ^
and contain
by nothing.
The list of regexes to check start with aa
abc
or 3@3
and contains >
is:
^aa ^abc ^3@3 >
Make that a properly quoted list and ask bash to use regexes (=~
):
check_func()
matched=1
for test_regex in '^aa' '^abc' '^3@3' '>'; do
if [[ $var =~ $test_regex ]] ; then
matched=0
break
fi
done
return "$matched"
var='aaIsAMatch'
if check_func; then
echo "A match was found"
fi
The function has hard-coded the list of matches and the name of the var.
Giving the list of regex in an array variable and the value to test on the first argument:
check_func()
local matched; matched=1
for t in "$test_regex[@]"; do
[[ $1 =~ $t ]] && matched=0; break;
done
return "$matched"
test_regex=('^aa' '^abc' '^3@3' '>')
if check_func 'aaIsAMatch'; then
echo "A match was found"
fi
The function could be further improved to use the name of a variable (instead of a value) as the first argument.
posix
As there is no regex in posix shells and the only way to test is a case statement, we must use a case statement. Sadly, for older shells ([no extended globs available][1]) we must loop to make all tests. And, the globs need to be:
'aa*' 'abc*' '3@3*' '*>*'
An script example that tests several input strings against several globs:
check_func() :
matched=1
value=$1; shift
for t in "$@"; do
case $value in $t) matched=0; #break;; esac
echo "matched $value with $t"
;;
esac
done
return "$matched"
for var in abdg wabcde aadef abcde 3@3hello hmm3@3hell 'we>we' 'a>dfff' 'dfd>' 'a> de' 'a*> fg'; do
if check_func "$var" 'aa*' 'abc*' '3@3*' '*>*'; then
echo "========A match was found for "$var""
fi
done
A simpler version of the function to exactly match your request:
check_func() :
matched=1
value=$1; shift
for t in "$@"; do
case $value in $t) matched=0; break;; esac
done
return "$matched"
add a comment |
Revised based on clarification to the question:
This is less elegant (and much less flexible),
but more compact than the other answers,
check_func()
case "$1" in
( aa*
This returns true for aardvark
, abcdef
, 3@3com.com
and 12>5
.
And, of course, also aard>vark
, abc<def>ghi
and 3@3>3
.
add a comment |
Here's what the case
statement does: take the second parameter to the function ($2
). If it matches the pattern "$1"*
, i.e. the first argument to the function followed by anything, then execute true
and end the case
statement. true
does nothing and returns the status 0. Otherwise, if it matches *
, i.e. anything, execute false
and end the case
statement. false
does nothing and returns the status 1. Thus the case
statement has the status 0 if the second parameter starts with the first parameter and 1 otherwise. Since this is the last (and only) statement in the function, the function returns 0 if the second parameter starts with the first parameter and 1 otherwise.
Conditional statements such as if
in the shell consider a statement to be true if it returns 0 and false otherwise. Hence if beginswith "$var" "string"; then echo yes; else echo no; fi
prints yes
if the value of var
starts with string
and no
otherwise.
There are several alternative ways to write this function. For example the author could have used return 0
or return 1
instead of true
and false
, since they are the last statement in the function. The way the function was written makes it possible to use its body directly without wrapping it in a function, by just changing references to the function parameters ($1
and $2
) to whatever strings you want to work with.
To allow multiple prefixes, iterate over them in a loop. As soon as you've found a matching prefix, return from the function, with a true status (0). If none of the prefixes match, return a false status (conventionally 1).
# begins_with STRING PREFIX1 PREFIX2...
# Test if STRING starts with any of PREFIX1, PREFIX2, ...
begins_with ()
string=$1
shift
for prefix in "$@"; do
case "$string" in
"$prefix"*) return 0;;
esac
done
return 1
if begins_with "$var" 'aa' 'abc' '3@3'; then
echo "The value starts with one of the permitted prefixes"
fi
To test for a suffix, use the pattern *"$suffix"
instead of "$prefix"*
. To test for a substring, use *"$substring"*
. Note that the double quotes are necessary here, otherwise the variable would be interpreted as a pattern. For example:
suffix='?'
case "$var" in
*"$suffix") echo "The value of var ends with a question mark";;
esac
case "$var" in
*$suffix) echo "The value of var is not empty";;
esac
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
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',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
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
);
);
No Imaginatition is a new contributor. Be nice, and check out our Code of Conduct.
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%2funix.stackexchange.com%2fquestions%2f523625%2fwrite-a-function-that-checks-if-a-string-starts-with-or-contains-something%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
check_prefixes ()
value=$1
for prefix in aa abc 3@3; do
case $value in
"$prefix"*) return 0
esac
done
return 1
check_contains_gt ()
value=$1
case $value in
*">"*) return 0
esac
return 1
var='aa>'
if check_prefixes "$var" && check_contains_gt "$var"; then
printf '"%s" contains ">" and starts with one of the prefixesn' "$var"
fi
I divided the tests up into two functions. Both use case ... esac
and returns success (zero) as soon as this can be determined. If nothing matches, failure (1) is returned.
To make the list of prefixes more of a dynamic list, one could possibly write the first function as
check_prefixes ()
value=$1
shift
for prefix do
case $value in
"$prefix"*) return 0
esac
done
return 1
(the value to inspect is the first argument, which we save in value
and then shift
off the list of arguments to the function; we then iterate over the remaining arguments) and then call it as
check_prefixes "$var" aa abc 3@3
The second function could be changed in a similar manner, into
check_contains ()
value=$1
shift
case $value in
*"$1"*) return 0
esac
return 1
(to check for some arbitrary substring), or
check_contains_oneof ()
value=$1
shift
for substring do
case $value in
*"$substring"*) return 0
esac
done
return 1
(to check for any of a number of substrings)
Thanks. My intended logic is with a logical or instead of a logical and. Should it bevalue
instead ofvar
in the first function's definition?
– No Imaginatition
Jun 7 at 23:12
@NoImaginatition OK, just change the logic in the code calling the functions (||
instead of&&
). Yes, that's a typo in my code, I'll fix it at once, thanks.
– Kusalananda♦
Jun 7 at 23:14
I'm trying to combine both functions into one by definingcheck_func()
, but it won't work forecho a >file
. Any idea why?
– No Imaginatition
Jun 7 at 23:16
@NoImaginatition Always double quote variable expansions ("$1"
) unless you know exactly in what contexts this is not needed.
– Kusalananda♦
Jun 7 at 23:19
Great, it worked. If it's not much to ask, what is it that it makes it fail without the double quotes? I tried to test if it would expand the second call of$1
, and it seems to expand. I tested it withtest () echo $1 $1;
and it worked fine.
– No Imaginatition
Jun 7 at 23:23
add a comment |
check_prefixes ()
value=$1
for prefix in aa abc 3@3; do
case $value in
"$prefix"*) return 0
esac
done
return 1
check_contains_gt ()
value=$1
case $value in
*">"*) return 0
esac
return 1
var='aa>'
if check_prefixes "$var" && check_contains_gt "$var"; then
printf '"%s" contains ">" and starts with one of the prefixesn' "$var"
fi
I divided the tests up into two functions. Both use case ... esac
and returns success (zero) as soon as this can be determined. If nothing matches, failure (1) is returned.
To make the list of prefixes more of a dynamic list, one could possibly write the first function as
check_prefixes ()
value=$1
shift
for prefix do
case $value in
"$prefix"*) return 0
esac
done
return 1
(the value to inspect is the first argument, which we save in value
and then shift
off the list of arguments to the function; we then iterate over the remaining arguments) and then call it as
check_prefixes "$var" aa abc 3@3
The second function could be changed in a similar manner, into
check_contains ()
value=$1
shift
case $value in
*"$1"*) return 0
esac
return 1
(to check for some arbitrary substring), or
check_contains_oneof ()
value=$1
shift
for substring do
case $value in
*"$substring"*) return 0
esac
done
return 1
(to check for any of a number of substrings)
Thanks. My intended logic is with a logical or instead of a logical and. Should it bevalue
instead ofvar
in the first function's definition?
– No Imaginatition
Jun 7 at 23:12
@NoImaginatition OK, just change the logic in the code calling the functions (||
instead of&&
). Yes, that's a typo in my code, I'll fix it at once, thanks.
– Kusalananda♦
Jun 7 at 23:14
I'm trying to combine both functions into one by definingcheck_func()
, but it won't work forecho a >file
. Any idea why?
– No Imaginatition
Jun 7 at 23:16
@NoImaginatition Always double quote variable expansions ("$1"
) unless you know exactly in what contexts this is not needed.
– Kusalananda♦
Jun 7 at 23:19
Great, it worked. If it's not much to ask, what is it that it makes it fail without the double quotes? I tried to test if it would expand the second call of$1
, and it seems to expand. I tested it withtest () echo $1 $1;
and it worked fine.
– No Imaginatition
Jun 7 at 23:23
add a comment |
check_prefixes ()
value=$1
for prefix in aa abc 3@3; do
case $value in
"$prefix"*) return 0
esac
done
return 1
check_contains_gt ()
value=$1
case $value in
*">"*) return 0
esac
return 1
var='aa>'
if check_prefixes "$var" && check_contains_gt "$var"; then
printf '"%s" contains ">" and starts with one of the prefixesn' "$var"
fi
I divided the tests up into two functions. Both use case ... esac
and returns success (zero) as soon as this can be determined. If nothing matches, failure (1) is returned.
To make the list of prefixes more of a dynamic list, one could possibly write the first function as
check_prefixes ()
value=$1
shift
for prefix do
case $value in
"$prefix"*) return 0
esac
done
return 1
(the value to inspect is the first argument, which we save in value
and then shift
off the list of arguments to the function; we then iterate over the remaining arguments) and then call it as
check_prefixes "$var" aa abc 3@3
The second function could be changed in a similar manner, into
check_contains ()
value=$1
shift
case $value in
*"$1"*) return 0
esac
return 1
(to check for some arbitrary substring), or
check_contains_oneof ()
value=$1
shift
for substring do
case $value in
*"$substring"*) return 0
esac
done
return 1
(to check for any of a number of substrings)
check_prefixes ()
value=$1
for prefix in aa abc 3@3; do
case $value in
"$prefix"*) return 0
esac
done
return 1
check_contains_gt ()
value=$1
case $value in
*">"*) return 0
esac
return 1
var='aa>'
if check_prefixes "$var" && check_contains_gt "$var"; then
printf '"%s" contains ">" and starts with one of the prefixesn' "$var"
fi
I divided the tests up into two functions. Both use case ... esac
and returns success (zero) as soon as this can be determined. If nothing matches, failure (1) is returned.
To make the list of prefixes more of a dynamic list, one could possibly write the first function as
check_prefixes ()
value=$1
shift
for prefix do
case $value in
"$prefix"*) return 0
esac
done
return 1
(the value to inspect is the first argument, which we save in value
and then shift
off the list of arguments to the function; we then iterate over the remaining arguments) and then call it as
check_prefixes "$var" aa abc 3@3
The second function could be changed in a similar manner, into
check_contains ()
value=$1
shift
case $value in
*"$1"*) return 0
esac
return 1
(to check for some arbitrary substring), or
check_contains_oneof ()
value=$1
shift
for substring do
case $value in
*"$substring"*) return 0
esac
done
return 1
(to check for any of a number of substrings)
edited Jun 7 at 23:14
answered Jun 7 at 20:02
Kusalananda♦Kusalananda
151k18290477
151k18290477
Thanks. My intended logic is with a logical or instead of a logical and. Should it bevalue
instead ofvar
in the first function's definition?
– No Imaginatition
Jun 7 at 23:12
@NoImaginatition OK, just change the logic in the code calling the functions (||
instead of&&
). Yes, that's a typo in my code, I'll fix it at once, thanks.
– Kusalananda♦
Jun 7 at 23:14
I'm trying to combine both functions into one by definingcheck_func()
, but it won't work forecho a >file
. Any idea why?
– No Imaginatition
Jun 7 at 23:16
@NoImaginatition Always double quote variable expansions ("$1"
) unless you know exactly in what contexts this is not needed.
– Kusalananda♦
Jun 7 at 23:19
Great, it worked. If it's not much to ask, what is it that it makes it fail without the double quotes? I tried to test if it would expand the second call of$1
, and it seems to expand. I tested it withtest () echo $1 $1;
and it worked fine.
– No Imaginatition
Jun 7 at 23:23
add a comment |
Thanks. My intended logic is with a logical or instead of a logical and. Should it bevalue
instead ofvar
in the first function's definition?
– No Imaginatition
Jun 7 at 23:12
@NoImaginatition OK, just change the logic in the code calling the functions (||
instead of&&
). Yes, that's a typo in my code, I'll fix it at once, thanks.
– Kusalananda♦
Jun 7 at 23:14
I'm trying to combine both functions into one by definingcheck_func()
, but it won't work forecho a >file
. Any idea why?
– No Imaginatition
Jun 7 at 23:16
@NoImaginatition Always double quote variable expansions ("$1"
) unless you know exactly in what contexts this is not needed.
– Kusalananda♦
Jun 7 at 23:19
Great, it worked. If it's not much to ask, what is it that it makes it fail without the double quotes? I tried to test if it would expand the second call of$1
, and it seems to expand. I tested it withtest () echo $1 $1;
and it worked fine.
– No Imaginatition
Jun 7 at 23:23
Thanks. My intended logic is with a logical or instead of a logical and. Should it be
value
instead of var
in the first function's definition?– No Imaginatition
Jun 7 at 23:12
Thanks. My intended logic is with a logical or instead of a logical and. Should it be
value
instead of var
in the first function's definition?– No Imaginatition
Jun 7 at 23:12
@NoImaginatition OK, just change the logic in the code calling the functions (
||
instead of &&
). Yes, that's a typo in my code, I'll fix it at once, thanks.– Kusalananda♦
Jun 7 at 23:14
@NoImaginatition OK, just change the logic in the code calling the functions (
||
instead of &&
). Yes, that's a typo in my code, I'll fix it at once, thanks.– Kusalananda♦
Jun 7 at 23:14
I'm trying to combine both functions into one by defining
check_func()
, but it won't work for echo a >file
. Any idea why?– No Imaginatition
Jun 7 at 23:16
I'm trying to combine both functions into one by defining
check_func()
, but it won't work for echo a >file
. Any idea why?– No Imaginatition
Jun 7 at 23:16
@NoImaginatition Always double quote variable expansions (
"$1"
) unless you know exactly in what contexts this is not needed.– Kusalananda♦
Jun 7 at 23:19
@NoImaginatition Always double quote variable expansions (
"$1"
) unless you know exactly in what contexts this is not needed.– Kusalananda♦
Jun 7 at 23:19
Great, it worked. If it's not much to ask, what is it that it makes it fail without the double quotes? I tried to test if it would expand the second call of
$1
, and it seems to expand. I tested it with test () echo $1 $1;
and it worked fine.– No Imaginatition
Jun 7 at 23:23
Great, it worked. If it's not much to ask, what is it that it makes it fail without the double quotes? I tried to test if it would expand the second call of
$1
, and it seems to expand. I tested it with test () echo $1 $1;
and it worked fine.– No Imaginatition
Jun 7 at 23:23
add a comment |
For bash:
Using the properties of regex you can write start
with ^
and contain
by nothing.
The list of regexes to check start with aa
abc
or 3@3
and contains >
is:
^aa ^abc ^3@3 >
Make that a properly quoted list and ask bash to use regexes (=~
):
check_func()
matched=1
for test_regex in '^aa' '^abc' '^3@3' '>'; do
if [[ $var =~ $test_regex ]] ; then
matched=0
break
fi
done
return "$matched"
var='aaIsAMatch'
if check_func; then
echo "A match was found"
fi
The function has hard-coded the list of matches and the name of the var.
Giving the list of regex in an array variable and the value to test on the first argument:
check_func()
local matched; matched=1
for t in "$test_regex[@]"; do
[[ $1 =~ $t ]] && matched=0; break;
done
return "$matched"
test_regex=('^aa' '^abc' '^3@3' '>')
if check_func 'aaIsAMatch'; then
echo "A match was found"
fi
The function could be further improved to use the name of a variable (instead of a value) as the first argument.
posix
As there is no regex in posix shells and the only way to test is a case statement, we must use a case statement. Sadly, for older shells ([no extended globs available][1]) we must loop to make all tests. And, the globs need to be:
'aa*' 'abc*' '3@3*' '*>*'
An script example that tests several input strings against several globs:
check_func() :
matched=1
value=$1; shift
for t in "$@"; do
case $value in $t) matched=0; #break;; esac
echo "matched $value with $t"
;;
esac
done
return "$matched"
for var in abdg wabcde aadef abcde 3@3hello hmm3@3hell 'we>we' 'a>dfff' 'dfd>' 'a> de' 'a*> fg'; do
if check_func "$var" 'aa*' 'abc*' '3@3*' '*>*'; then
echo "========A match was found for "$var""
fi
done
A simpler version of the function to exactly match your request:
check_func() :
matched=1
value=$1; shift
for t in "$@"; do
case $value in $t) matched=0; break;; esac
done
return "$matched"
add a comment |
For bash:
Using the properties of regex you can write start
with ^
and contain
by nothing.
The list of regexes to check start with aa
abc
or 3@3
and contains >
is:
^aa ^abc ^3@3 >
Make that a properly quoted list and ask bash to use regexes (=~
):
check_func()
matched=1
for test_regex in '^aa' '^abc' '^3@3' '>'; do
if [[ $var =~ $test_regex ]] ; then
matched=0
break
fi
done
return "$matched"
var='aaIsAMatch'
if check_func; then
echo "A match was found"
fi
The function has hard-coded the list of matches and the name of the var.
Giving the list of regex in an array variable and the value to test on the first argument:
check_func()
local matched; matched=1
for t in "$test_regex[@]"; do
[[ $1 =~ $t ]] && matched=0; break;
done
return "$matched"
test_regex=('^aa' '^abc' '^3@3' '>')
if check_func 'aaIsAMatch'; then
echo "A match was found"
fi
The function could be further improved to use the name of a variable (instead of a value) as the first argument.
posix
As there is no regex in posix shells and the only way to test is a case statement, we must use a case statement. Sadly, for older shells ([no extended globs available][1]) we must loop to make all tests. And, the globs need to be:
'aa*' 'abc*' '3@3*' '*>*'
An script example that tests several input strings against several globs:
check_func() :
matched=1
value=$1; shift
for t in "$@"; do
case $value in $t) matched=0; #break;; esac
echo "matched $value with $t"
;;
esac
done
return "$matched"
for var in abdg wabcde aadef abcde 3@3hello hmm3@3hell 'we>we' 'a>dfff' 'dfd>' 'a> de' 'a*> fg'; do
if check_func "$var" 'aa*' 'abc*' '3@3*' '*>*'; then
echo "========A match was found for "$var""
fi
done
A simpler version of the function to exactly match your request:
check_func() :
matched=1
value=$1; shift
for t in "$@"; do
case $value in $t) matched=0; break;; esac
done
return "$matched"
add a comment |
For bash:
Using the properties of regex you can write start
with ^
and contain
by nothing.
The list of regexes to check start with aa
abc
or 3@3
and contains >
is:
^aa ^abc ^3@3 >
Make that a properly quoted list and ask bash to use regexes (=~
):
check_func()
matched=1
for test_regex in '^aa' '^abc' '^3@3' '>'; do
if [[ $var =~ $test_regex ]] ; then
matched=0
break
fi
done
return "$matched"
var='aaIsAMatch'
if check_func; then
echo "A match was found"
fi
The function has hard-coded the list of matches and the name of the var.
Giving the list of regex in an array variable and the value to test on the first argument:
check_func()
local matched; matched=1
for t in "$test_regex[@]"; do
[[ $1 =~ $t ]] && matched=0; break;
done
return "$matched"
test_regex=('^aa' '^abc' '^3@3' '>')
if check_func 'aaIsAMatch'; then
echo "A match was found"
fi
The function could be further improved to use the name of a variable (instead of a value) as the first argument.
posix
As there is no regex in posix shells and the only way to test is a case statement, we must use a case statement. Sadly, for older shells ([no extended globs available][1]) we must loop to make all tests. And, the globs need to be:
'aa*' 'abc*' '3@3*' '*>*'
An script example that tests several input strings against several globs:
check_func() :
matched=1
value=$1; shift
for t in "$@"; do
case $value in $t) matched=0; #break;; esac
echo "matched $value with $t"
;;
esac
done
return "$matched"
for var in abdg wabcde aadef abcde 3@3hello hmm3@3hell 'we>we' 'a>dfff' 'dfd>' 'a> de' 'a*> fg'; do
if check_func "$var" 'aa*' 'abc*' '3@3*' '*>*'; then
echo "========A match was found for "$var""
fi
done
A simpler version of the function to exactly match your request:
check_func() :
matched=1
value=$1; shift
for t in "$@"; do
case $value in $t) matched=0; break;; esac
done
return "$matched"
For bash:
Using the properties of regex you can write start
with ^
and contain
by nothing.
The list of regexes to check start with aa
abc
or 3@3
and contains >
is:
^aa ^abc ^3@3 >
Make that a properly quoted list and ask bash to use regexes (=~
):
check_func()
matched=1
for test_regex in '^aa' '^abc' '^3@3' '>'; do
if [[ $var =~ $test_regex ]] ; then
matched=0
break
fi
done
return "$matched"
var='aaIsAMatch'
if check_func; then
echo "A match was found"
fi
The function has hard-coded the list of matches and the name of the var.
Giving the list of regex in an array variable and the value to test on the first argument:
check_func()
local matched; matched=1
for t in "$test_regex[@]"; do
[[ $1 =~ $t ]] && matched=0; break;
done
return "$matched"
test_regex=('^aa' '^abc' '^3@3' '>')
if check_func 'aaIsAMatch'; then
echo "A match was found"
fi
The function could be further improved to use the name of a variable (instead of a value) as the first argument.
posix
As there is no regex in posix shells and the only way to test is a case statement, we must use a case statement. Sadly, for older shells ([no extended globs available][1]) we must loop to make all tests. And, the globs need to be:
'aa*' 'abc*' '3@3*' '*>*'
An script example that tests several input strings against several globs:
check_func() :
matched=1
value=$1; shift
for t in "$@"; do
case $value in $t) matched=0; #break;; esac
echo "matched $value with $t"
;;
esac
done
return "$matched"
for var in abdg wabcde aadef abcde 3@3hello hmm3@3hell 'we>we' 'a>dfff' 'dfd>' 'a> de' 'a*> fg'; do
if check_func "$var" 'aa*' 'abc*' '3@3*' '*>*'; then
echo "========A match was found for "$var""
fi
done
A simpler version of the function to exactly match your request:
check_func() :
matched=1
value=$1; shift
for t in "$@"; do
case $value in $t) matched=0; break;; esac
done
return "$matched"
edited Jun 7 at 21:37
answered Jun 7 at 20:39
IsaacIsaac
13.2k12159
13.2k12159
add a comment |
add a comment |
Revised based on clarification to the question:
This is less elegant (and much less flexible),
but more compact than the other answers,
check_func()
case "$1" in
( aa*
This returns true for aardvark
, abcdef
, 3@3com.com
and 12>5
.
And, of course, also aard>vark
, abc<def>ghi
and 3@3>3
.
add a comment |
Revised based on clarification to the question:
This is less elegant (and much less flexible),
but more compact than the other answers,
check_func()
case "$1" in
( aa*
This returns true for aardvark
, abcdef
, 3@3com.com
and 12>5
.
And, of course, also aard>vark
, abc<def>ghi
and 3@3>3
.
add a comment |
Revised based on clarification to the question:
This is less elegant (and much less flexible),
but more compact than the other answers,
check_func()
case "$1" in
( aa*
This returns true for aardvark
, abcdef
, 3@3com.com
and 12>5
.
And, of course, also aard>vark
, abc<def>ghi
and 3@3>3
.
Revised based on clarification to the question:
This is less elegant (and much less flexible),
but more compact than the other answers,
check_func()
case "$1" in
( aa*
This returns true for aardvark
, abcdef
, 3@3com.com
and 12>5
.
And, of course, also aard>vark
, abc<def>ghi
and 3@3>3
.
edited Jun 7 at 23:54
answered Jun 7 at 20:24
G-ManG-Man
14.7k94175
14.7k94175
add a comment |
add a comment |
Here's what the case
statement does: take the second parameter to the function ($2
). If it matches the pattern "$1"*
, i.e. the first argument to the function followed by anything, then execute true
and end the case
statement. true
does nothing and returns the status 0. Otherwise, if it matches *
, i.e. anything, execute false
and end the case
statement. false
does nothing and returns the status 1. Thus the case
statement has the status 0 if the second parameter starts with the first parameter and 1 otherwise. Since this is the last (and only) statement in the function, the function returns 0 if the second parameter starts with the first parameter and 1 otherwise.
Conditional statements such as if
in the shell consider a statement to be true if it returns 0 and false otherwise. Hence if beginswith "$var" "string"; then echo yes; else echo no; fi
prints yes
if the value of var
starts with string
and no
otherwise.
There are several alternative ways to write this function. For example the author could have used return 0
or return 1
instead of true
and false
, since they are the last statement in the function. The way the function was written makes it possible to use its body directly without wrapping it in a function, by just changing references to the function parameters ($1
and $2
) to whatever strings you want to work with.
To allow multiple prefixes, iterate over them in a loop. As soon as you've found a matching prefix, return from the function, with a true status (0). If none of the prefixes match, return a false status (conventionally 1).
# begins_with STRING PREFIX1 PREFIX2...
# Test if STRING starts with any of PREFIX1, PREFIX2, ...
begins_with ()
string=$1
shift
for prefix in "$@"; do
case "$string" in
"$prefix"*) return 0;;
esac
done
return 1
if begins_with "$var" 'aa' 'abc' '3@3'; then
echo "The value starts with one of the permitted prefixes"
fi
To test for a suffix, use the pattern *"$suffix"
instead of "$prefix"*
. To test for a substring, use *"$substring"*
. Note that the double quotes are necessary here, otherwise the variable would be interpreted as a pattern. For example:
suffix='?'
case "$var" in
*"$suffix") echo "The value of var ends with a question mark";;
esac
case "$var" in
*$suffix) echo "The value of var is not empty";;
esac
add a comment |
Here's what the case
statement does: take the second parameter to the function ($2
). If it matches the pattern "$1"*
, i.e. the first argument to the function followed by anything, then execute true
and end the case
statement. true
does nothing and returns the status 0. Otherwise, if it matches *
, i.e. anything, execute false
and end the case
statement. false
does nothing and returns the status 1. Thus the case
statement has the status 0 if the second parameter starts with the first parameter and 1 otherwise. Since this is the last (and only) statement in the function, the function returns 0 if the second parameter starts with the first parameter and 1 otherwise.
Conditional statements such as if
in the shell consider a statement to be true if it returns 0 and false otherwise. Hence if beginswith "$var" "string"; then echo yes; else echo no; fi
prints yes
if the value of var
starts with string
and no
otherwise.
There are several alternative ways to write this function. For example the author could have used return 0
or return 1
instead of true
and false
, since they are the last statement in the function. The way the function was written makes it possible to use its body directly without wrapping it in a function, by just changing references to the function parameters ($1
and $2
) to whatever strings you want to work with.
To allow multiple prefixes, iterate over them in a loop. As soon as you've found a matching prefix, return from the function, with a true status (0). If none of the prefixes match, return a false status (conventionally 1).
# begins_with STRING PREFIX1 PREFIX2...
# Test if STRING starts with any of PREFIX1, PREFIX2, ...
begins_with ()
string=$1
shift
for prefix in "$@"; do
case "$string" in
"$prefix"*) return 0;;
esac
done
return 1
if begins_with "$var" 'aa' 'abc' '3@3'; then
echo "The value starts with one of the permitted prefixes"
fi
To test for a suffix, use the pattern *"$suffix"
instead of "$prefix"*
. To test for a substring, use *"$substring"*
. Note that the double quotes are necessary here, otherwise the variable would be interpreted as a pattern. For example:
suffix='?'
case "$var" in
*"$suffix") echo "The value of var ends with a question mark";;
esac
case "$var" in
*$suffix) echo "The value of var is not empty";;
esac
add a comment |
Here's what the case
statement does: take the second parameter to the function ($2
). If it matches the pattern "$1"*
, i.e. the first argument to the function followed by anything, then execute true
and end the case
statement. true
does nothing and returns the status 0. Otherwise, if it matches *
, i.e. anything, execute false
and end the case
statement. false
does nothing and returns the status 1. Thus the case
statement has the status 0 if the second parameter starts with the first parameter and 1 otherwise. Since this is the last (and only) statement in the function, the function returns 0 if the second parameter starts with the first parameter and 1 otherwise.
Conditional statements such as if
in the shell consider a statement to be true if it returns 0 and false otherwise. Hence if beginswith "$var" "string"; then echo yes; else echo no; fi
prints yes
if the value of var
starts with string
and no
otherwise.
There are several alternative ways to write this function. For example the author could have used return 0
or return 1
instead of true
and false
, since they are the last statement in the function. The way the function was written makes it possible to use its body directly without wrapping it in a function, by just changing references to the function parameters ($1
and $2
) to whatever strings you want to work with.
To allow multiple prefixes, iterate over them in a loop. As soon as you've found a matching prefix, return from the function, with a true status (0). If none of the prefixes match, return a false status (conventionally 1).
# begins_with STRING PREFIX1 PREFIX2...
# Test if STRING starts with any of PREFIX1, PREFIX2, ...
begins_with ()
string=$1
shift
for prefix in "$@"; do
case "$string" in
"$prefix"*) return 0;;
esac
done
return 1
if begins_with "$var" 'aa' 'abc' '3@3'; then
echo "The value starts with one of the permitted prefixes"
fi
To test for a suffix, use the pattern *"$suffix"
instead of "$prefix"*
. To test for a substring, use *"$substring"*
. Note that the double quotes are necessary here, otherwise the variable would be interpreted as a pattern. For example:
suffix='?'
case "$var" in
*"$suffix") echo "The value of var ends with a question mark";;
esac
case "$var" in
*$suffix) echo "The value of var is not empty";;
esac
Here's what the case
statement does: take the second parameter to the function ($2
). If it matches the pattern "$1"*
, i.e. the first argument to the function followed by anything, then execute true
and end the case
statement. true
does nothing and returns the status 0. Otherwise, if it matches *
, i.e. anything, execute false
and end the case
statement. false
does nothing and returns the status 1. Thus the case
statement has the status 0 if the second parameter starts with the first parameter and 1 otherwise. Since this is the last (and only) statement in the function, the function returns 0 if the second parameter starts with the first parameter and 1 otherwise.
Conditional statements such as if
in the shell consider a statement to be true if it returns 0 and false otherwise. Hence if beginswith "$var" "string"; then echo yes; else echo no; fi
prints yes
if the value of var
starts with string
and no
otherwise.
There are several alternative ways to write this function. For example the author could have used return 0
or return 1
instead of true
and false
, since they are the last statement in the function. The way the function was written makes it possible to use its body directly without wrapping it in a function, by just changing references to the function parameters ($1
and $2
) to whatever strings you want to work with.
To allow multiple prefixes, iterate over them in a loop. As soon as you've found a matching prefix, return from the function, with a true status (0). If none of the prefixes match, return a false status (conventionally 1).
# begins_with STRING PREFIX1 PREFIX2...
# Test if STRING starts with any of PREFIX1, PREFIX2, ...
begins_with ()
string=$1
shift
for prefix in "$@"; do
case "$string" in
"$prefix"*) return 0;;
esac
done
return 1
if begins_with "$var" 'aa' 'abc' '3@3'; then
echo "The value starts with one of the permitted prefixes"
fi
To test for a suffix, use the pattern *"$suffix"
instead of "$prefix"*
. To test for a substring, use *"$substring"*
. Note that the double quotes are necessary here, otherwise the variable would be interpreted as a pattern. For example:
suffix='?'
case "$var" in
*"$suffix") echo "The value of var ends with a question mark";;
esac
case "$var" in
*$suffix) echo "The value of var is not empty";;
esac
answered Jun 7 at 20:16
GillesGilles
558k13411431654
558k13411431654
add a comment |
add a comment |
No Imaginatition is a new contributor. Be nice, and check out our Code of Conduct.
No Imaginatition is a new contributor. Be nice, and check out our Code of Conduct.
No Imaginatition is a new contributor. Be nice, and check out our Code of Conduct.
No Imaginatition is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- 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%2funix.stackexchange.com%2fquestions%2f523625%2fwrite-a-function-that-checks-if-a-string-starts-with-or-contains-something%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
It just occurred to me that your question is ambiguous. Do you mean (1) I want to check if
var
starts withaa
. I want to check ifvar
starts withabc
. I want to check ifvar
starts with3@3
. And I want to check ifvar
contains>
. ? Or do you mean (2) I want to check ifvar
starts withaa
,abc
or3@3
, and it also contains>
. ?– G-Man
Jun 7 at 21:23
@G-Man The first one. Thanks for bringing that up.
– No Imaginatition
Jun 7 at 22:44