2

I am writing a bash script which accepts a list of CSV files as arguments and outputs e-mail addresses only found in the first file. To accomplish this, for each record in the first CSV file I look up the e-mail address field and read its contents into a shell variable. Then, I use grep -iE with the following regular expression to look up the e-mail address just found in all the remaining files, making sure that it is not a substring (e.g. [email protected] is not the same as [email protected]), and allowing it to be at the beginning or end of a record:

"^(.*,)?($EMAIL_ADDRESS|\"$EMAIL_ADDRESS\")(,.*)?\$"

A problem with this approach is that e-mail addresses contain dots which have a special meaning in regular expressions. My questions are:

  1. How can I avoid this problem in an elegant way?
  2. How can I avoid this problem in a more general context, e.g. when the value to look up is not an e-mail address but some free text and might contain other special characters as well?
4
  • 1
    Use Perl instead of bash: quotemeta.
    – choroba
    Commented Apr 14, 2015 at 9:47
  • awk -F, '$2 == "[email protected]"'? Commented Apr 14, 2015 at 9:47
  • 1
    use a backslash \. in front of the dot to escape it. you probably need two backslashes \\. to get the shell to pass one to the program.
    – Skaperen
    Commented Apr 14, 2015 at 10:11
  • You can use grep -F to do not treat pattern as regular expression, just like a string and -w option (whole word) which mean that pattern should fill full "word" ( so " he@" is not compare " she@")
    – Costas
    Commented Apr 14, 2015 at 11:25

1 Answer 1

1

in perl regexp (grep -P ...) you may use \Q...\E to protect meta chars

grep -P "(^|,)\Q$EMAIL\E(,|$)" file.csv

where:

  • (^|,) = start of field
  • (,|$) = end of field
3
  • Don't you need to escape the $? Also, where are \Q and \E documented?
    – SJU
    Commented Apr 15, 2015 at 10:15
  • In bash both ...$) and ...\$) work. Escaping is shell dependent. \Q...\E is document in any tutorial about perl-like regexp. See also the "quotemeta" link of @choroba comment.
    – JJoao
    Commented Apr 15, 2015 at 11:13
  • This can fail if the variable $EMAIL contains a literal \E. Here's an example: x='\E^a'; printf %s\\n "$x" a | grep -P "\Q$x\E". Grep doesn't match the value $x but matches the string a which is different from $x.
    – Socowi
    Commented Jul 25, 2019 at 10:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .