1

I am attempting to check for proper formatting at the start of a string in a bash script.

The expected format is like the below where the string must always begin with "ABCDEFG-" (exact letters and order) and the numbers would vary but be at least 3 digits. Everything after the 3rd digit is a do not care. Expected start of string: "ABCDEFG-1234"

I am using the below code snippet.

[ $(echo "$str" | grep -E "ABCDEFG-[0-9][0-9][0-9]") ] && echo "yes"

str1 = "ABCDEFG-1234"

str2 = "ABCDEFG-1234 - Some more text"

When I use str1 in place of str everything works ok and yes is printed.

When I use str2 in place of str i get the below error

[: ABCDEFG-1234: unary operator expected

I am pretty new to working with bash scripts so any help would be appreciated.

2
  • The smallest change necessary to make your code work would be just to add quotes and a -n: [ -n "$(echo "$str" | grep -E "ABCDEFG-[0-9][0-9][0-9]")" ] && echo "yes" -- that way the output from grep isn't string-split and passed to [ ] as separate arguments, which was the immediate cause of your error. That said, that approach is unnecessarily inefficient and baroque, when grep can directly emit a true or false exit status based on whether it matched, with no need for [ ] or output parsing at all, and when the shell can do comparisons without needing any external tool like grep. Commented Oct 3, 2014 at 20:27
  • (...and the -n is only necessary in some pathological cases; in the common case, the quotes would be enough). Commented Oct 3, 2014 at 20:29

2 Answers 2

6

If this is bash, you have no reason to use grep for this at all; the shell has built-in regular expression support.

re="ABCDEFG-[0-9][0-9][0-9]"
[[ $str =~ $re ]] && echo "yes"

That said, you might want your regex to be anchored if you want a match in the beginning rather than anywhere in the content:

re="^ABCDEFG-[0-9][0-9][0-9]"
[[ $str =~ $re ]] && echo "yes"

That said, this doesn't need to be an ERE at all -- a glob-style pattern match would also be adequate:

if [[ $str = ABCDEFG-[0-9][0-9][0-9]* ]]; then echo "yes"; fi
Sign up to request clarification or add additional context in comments.

Comments

0

Try grep -E "ABCDEFG-[0-9][0-9][0-9].*"

1 Comment

Doesn't solve the problem, which is due to failing to quote the output of grep into a single token for being passed to test. (Of course, if one used grep -q and ran if echo "$str" | grep -q -E ...; then..., then it'd be moot; involving test at all is overcomplicating things unnecessarily).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.