Skip to content
Advertisement

How to “grep” in array with dot “.” precisely?

I’m trying to check if the user input $1 exist in an array. And here is my code:

array=(
aaa.bbb.ccc
ccc.ddd.aaa
)

echo ${array[@]} | grep -o -w "$1"

What I expect is only “aaa.bbb.ccc” or “ccc.ddd.aaa” can be found. However, in this case, like “aaa” or “ccc” can also pass the validation. Seems like the dot is not treated as part of the string.

Should I use regex or other grep option?

Advertisement

Answer

It sounds like you want:

  • literal string matching
  • against entire input lines.

Therefore, use -F (for literal matching) and -x for whole-line matching:

array=(
  aaa.bbb.ccc
  ccc.ddd.aaa
)

printf '%sn' "${array[@]}" | grep -Fx "$1"

Now, only literal strings aaa.bbb.ccc and ccc.ddd.aaa will match, not substrings such as aaa.
Since you’re matching the entire line, use of -o (to only output the matching part of each line) is unnecessary.

Also note how printf '%sn' "${array[@]}" must be used to print each array element on its own line, whereas echo ${array[@]} prints the elements on a single line (with whitespace normalization due to word-splitting and potential globbing applied, because ${array[@]} is not enclosed in "...").


The problem with your approach:

  • grep defaults to (basic) regular expressions, so a $1 value containing . would result in that . being interpreted to mean “any single character”.

  • echo ${array[@]} is problematic due to potentially unwanted whitespace normalization and globbing, as stated; echo "${array[@]}" | grep -Fwo "$1" would be an improvement, but bears a slight risk of false positives.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement