3

I'm trying to follow this question/answer from Server Fault: In tail -f, how do I filter out stuff that has certain keywords?

The following is producing egrep: empty (sub)expression:

# Respect user's preferred flags, but filter the stuff we explicitly test
#  Retain allowed flags in ADD_CXXFLAGS
if [ ! -z "CXXFLAGS" ]; then
    ADD_CXXFLAGS=$(echo "$CXXFLAGS" | egrep -v '(\-DDEBUG|\-DNDEBUG|\-O[0-9]|\-Os|\-Og|)')
else
    ADD_CXXFLAGS=
fi

echo "User CXXFLAGS: $CXXFLAGS"
echo "Retained CXXFLAGS: $ADD_CXXFLAGS"

Google was not very helpful in providing me suggestions: "egrep: empty (sub)expression". Half of them looked Chinese (literally).

I've tried the simple stuff I know, like replacing single quote with double quote, escaping and not escaping the dash, and similar beginner stuff.

I'm on OS X, which is usually a flavor of the BDSs. But this might be some non-standard Apple behavior.

What's wrong with the expression or sub-expression?


Later, the script uses it like follows. For example, we want to remove -DDEBUG and -DNDEBUG, but retain -maes, -mrdrnd and -mrdseed. Hence the reason we want to filter out some flags, but not other.

# Test Debug build, -O2
export CXXFLAGS="-DDEBUG -g2 -O2 $ADD_CXXFLAGS"
make...

# Test Release build, -O2
export CXXFLAGS="-DNDEBUG -g2 -O2 $ADD_CXXFLAGS"
make...

# Test Debug build, -O3
export CXXFLAGS="-DDEBUG -g2 -O3 $ADD_CXXFLAGS"
make...

# Test Release build, -O3
export CXXFLAGS="-DNDEBUG -g2 -O3 $ADD_CXXFLAGS"
make...

...
1
  • Thanks for the help everyone. This should be the last question, and I can go through and accept best answers once everything works (for this and the other question). Commented Oct 27, 2015 at 7:29

2 Answers 2

3

Replace:

egrep -v '(\-DDEBUG|\-DNDEBUG|\-O[0-9]|\-Os|\-Og|)'

With:

egrep -v '(\-DDEBUG|\-DNDEBUG|\-O[0-9]|\-Os|\-Og)'

This removes the empty subexpression at the end of the egrep regex.

Discussion

Compare the following two regexes, the first without an empty subexpression and the second with one:

$ echo abc | egrep -v '(none|such)'
abc
$ echo abc | egrep -v '(none|such|)'
$

(none|such) matches either none or such. By contrast, (none|such|) matches either none or such or nothing at all. Since all input matches the last, the egrep -v command removes everything from the input.

1
  • Thank you very much. Interestingly, Linux took it without complaint. I can't apologize enough for these beginner questions.... Commented Oct 27, 2015 at 7:51
2

Your error is the empty |). However, if you want to remove certain words from a single line, egrep is not going to help you. You need to use something like sed:

export ADD_CXXFLAGS=$(echo " $CXXFLAGS " | sed 's/ /  /g;s/ \(-DDEBUG\|-DNDEBUG\|-O[0-9]\|-Os\|-Og\) / /g')

The above adds a space around the flags to simplify, then replaces any of your words by a space. Hence CXXFLAGS="-DDEBUG -g2 -O2 $ADD_CXXFLAGS" becomes ADD_CXXFLAGS=-g2.


Note you can do this sort of manipulation inside your Makefile instead:

ADD_CXXFLAGS=$(filter-out -DDEBUG -DNDEBUG -O1 -O2 -O3 -04 -O5 -O6 -O7 -O8 -O9 -Os -Og, $(CXXFLAGS))
3
  • "Note you can do this sort of manipulation inside your Makefile instead..." - exactly. I was looking for the shell's equivalent of filter-out, but I could not find it. And its the reason why I used "filter out" in the title of the question. Others searching for it should find it this question. Commented Oct 27, 2015 at 8:17
  • "if you want to remove certain words from a single line, egrep is not going to help you..." - I was suspicious of that, and I even reproduced the result you predicted. I thought it was something I was doing wrong or some behavior Apple changed. I was going to ask some other maintainers to test and comment... Commented Oct 27, 2015 at 8:20
  • I had to edit the sed and add to the start s/ / /g; to duplicate spaces. This is because my simple replacement of <space>keyword<space> by <space> does not allow two adjacent keywords to be removed, as the single intervening space is gobbled up, and sed does not try to use the replacement space. (We cannot use \b which means "word boundary", because - is not in the definition of a word.) Commented Oct 27, 2015 at 9:24

You must log in to answer this question.