I'm having trouble getting a string tool to provide what I need (due to my ignorance). I have a string based on CPU features. The string will change as different processors offer different features:# Example from a modern Core i5 4th genSUNCC_CXXFLAGS=-D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__ -D__AES__ -D__PCLMUL__ __AVX__ ...The string works great for Sun Studio 12.3 and above. For Sun Studio 12.2 and below, I can only use SSE2, SSE3, SSSE3, SSE4.1 and SSE4.2. AES and above defines cause an obscure error, so they must be filtered out of the flags.Put another way I need the intersection of the two sets:# Cannot use AES and above for SunCC 12.2ALLOWED_CXXFLAGS=-D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__# New processor, needs to be filtered due to old compilerSUNCC_CXXFLAGS=-D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__ -D__AES__ -D__PCLMUL__ __AVX__ ...I've seen a number of questions and answers with awk matching (and non-matching) regexes and lines. But I need to filter based on tokens in a single line.I tried the following, which does not produce expected results:$ echo -D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__ -D__AES__ -D__PCLMUL__ | \  nawk '!/(-D__SSE2__|-D__SSE3__|-D__SSSE3__)/'$Another twist: this is Solaris, so the tools don't have a lot of the options present in GNU tools. Its one of the reasons I tried awk instead of sed or grep.How can I filter out the tokens that don't match my set of tokens?
Awk and discarding non-matching tokens in a string?
awk;sed;solaris;string;filter
To select only the SSE flags, try:awk '/SSE/' ORS=' ' RS=' 'The key thing here is setting the record separators on input and output to a space.  That way, each option is accepted or rejected separately.For example:$ SUNCC_CXXFLAGS=-D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__ -D__AES__ -D__PCLMUL__ ...$ newFLAGS=$(echo $SUNCC_CXXFLAGS | awk '/SSE/' ORS=' ' RS=' ')$ echo $newFLAGS-D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__ SSE appears to be a tight enough match here.  If it isn't, we can be more specific:$ newFLAGS=$(echo $SUNCC_CXXFLAGS | awk '/^-D__(SSE2|SSE3|SSSE3|SSE4.1|SSE4.2)__/' ORS=' ' RS=' ')$ echo $newFLAGS-D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__ Alternative: excluding SSE and AES$ echo $SUNCC_CXXFLAGS | nawk '!/SSE|AES/' ORS=' ' RS=' '-D__PCLMUL__ ...Keeping options that match SSE or sse$ SUNCC_CXXFLAGS=-D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__ -D__AES__ -D__PCLMUL__ -xarch=sse3$ newFLAGS=$(echo $SUNCC_CXXFLAGS | awk '/SSE|sse/' ORS=' ' RS=' ')$ echo $newFLAGS-D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__ -xarch=sse3The change here is that we replaced the regex /SSE/ with /SSE|sse/.  Because the vertical bar, |, means logical-or, this matches either SSE or sse.