The reason lies in the way RegEx matches are processed (see here, e.g.): The string is evaluated from left to right, and - except for backreferences - every single symbol in the string must be matched by a token in the regular expression (which in the simplest case is the literal symbol itself), although the token can be implicit thanks to repetition operators.
The key point is that regular expressions do not describe "general properties of the entire string" (such as "starts and ends with s
"), but impose rules on the character level of the string. So, your regular expression
^s$
means: "start-of-string", followed by one s
, and immediately followed by "end-of-string". This would therefore only match the string that consists of the single letter s
. While technically this is a string starting and ending with s
, it is not what you are looking for.
If you want to match a string that starts with s
, has arbitrary characters in between, and ends with s
, you have to specify all of these explicitly.
To make it very explicit:
- A first iteration could look like this:
^s.*s$
This would match "string starting with s
, followed by zero or more characters of any kind (.*
), followed by s
at the end-of-string.
- Of course, this would not match the string that consists of only the character
s
. So, in the second iteration, we would make the part after the initial s
optional (see comment by @user414777):
^s(.*s)?$
This would then match "string starting with s
, followed by zero or one times (the ?
) 'a sub-string of zero or more characters of any kind, followed by an s
' (the content of the (...)
), and ending immediately after that".
Now, as you tagged your question with awk
, it could mean that you want to create a condition for an awk
rule that only applies if the line or a string starts and ends with s
. This could look like:
awk '/^s/ && /s$/ { ... }'
With grep
, such an AND-construction is not possible natively (the -e regex1 -e regex2
syntax would amount to an OR), but you can achieve it by piping:
grep "^s" sourcefile.txt | grep "s$"
^s$
but the question body says^$
without thes
. Which are you asking about? – shoover Oct 09 '20 at 03:38^$
in that first line in the same sense that they stated "If^
matches the beginning" instead of "If^s
matches the beginning", so the question would be about^s$
for the concrete example, but in general about^$
as a "combined anchor" at begin and end for whatever is inbetween. – AdminBee Oct 09 '20 at 08:35