strstr() alternative for bash
Question:
I need to search a string for a substring, if the substring is found print the string upto the end of the substring.i.e
str="this is a long string"
substring="long"
expected="this is a long"
I have tried bash string manipulation and failed. Tried to use an awk command, but I can’t get it right.
This works if substring is not in a variable, but I require it in a variable since the input varies.
awk -F'long' '{print $1}' <<<$str
awk -v myvar="$substring" -F'myvar' '{print $1}' <<<$str
prints the whole string.
Any help will be appreciated.
Answers:
If you looked for bash only solution, one of the options would be:
sfx="${str#*${substring}}"
expected="${str%"${sfx}"}"
Which uses prefix removal (of anything + $substring
) to determine the trailing part. And then uses suffix removal to trim that from $str
yielding your expected value.
Since you seem to be OK with answers beyond just shell (like using awk
), here’s similar with sed
:
echo "$str" | sed -e 's#^(.*'"${substring}"').*#1#'
-> match the whole line with anything up to and including $substring
being saved in the first group and replace that line with content of the first matched group.
note: both of these examples are not greedy and will match up to the first $substring
.
Including error handling for the case that the substring is not present:
str="this is a long string"
substring="long"
if [[ $str =~ (.*"$substring") ]]
then
expected=${BASH_REMATCH[1]}
else
echo ERROR: Substring not found >&2
fi
While the quotes around $substring
are not necessary for your concrete example, you would need them if substring
contained special regex characters.
# echo "$str" | awk -F'long' '{print $1FS}'
this is a long
I need to search a string for a substring, if the substring is found print the string upto the end of the substring.i.e
str="this is a long string"
substring="long"
expected="this is a long"
I have tried bash string manipulation and failed. Tried to use an awk command, but I can’t get it right.
This works if substring is not in a variable, but I require it in a variable since the input varies.
awk -F'long' '{print $1}' <<<$str
awk -v myvar="$substring" -F'myvar' '{print $1}' <<<$str
prints the whole string.
Any help will be appreciated.
If you looked for bash only solution, one of the options would be:
sfx="${str#*${substring}}"
expected="${str%"${sfx}"}"
Which uses prefix removal (of anything + $substring
) to determine the trailing part. And then uses suffix removal to trim that from $str
yielding your expected value.
Since you seem to be OK with answers beyond just shell (like using awk
), here’s similar with sed
:
echo "$str" | sed -e 's#^(.*'"${substring}"').*#1#'
-> match the whole line with anything up to and including $substring
being saved in the first group and replace that line with content of the first matched group.
note: both of these examples are not greedy and will match up to the first $substring
.
Including error handling for the case that the substring is not present:
str="this is a long string"
substring="long"
if [[ $str =~ (.*"$substring") ]]
then
expected=${BASH_REMATCH[1]}
else
echo ERROR: Substring not found >&2
fi
While the quotes around $substring
are not necessary for your concrete example, you would need them if substring
contained special regex characters.
# echo "$str" | awk -F'long' '{print $1FS}'
this is a long