awk 并丢弃字符串中不匹配的标记?

3 solaris sed awk string filter

我无法获得字符串工具来提供我需要的东西(由于我的无知)。我有一个基于 CPU 功能的字符串。字符串会随着不同的处理器提供不同的特性而改变

# Example from a modern Core i5 4th gen
SUNCC_CXXFLAGS="-D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__ -D__AES__ -D__PCLMUL__ __AVX__ ..."
Run Code Online (Sandbox Code Playgroud)

该字符串非常适用于 Sun Studio 12.3 及更高版本。对于Sun Studio 12.2 及以下版本,我只能使用 SSE2、SSE3、SSSE3、SSE4.1 和 SSE4.2。AES 及以上定义会导致一个模糊的错误,因此必须将它们从标志中过滤掉。

换句话说,我需要两组的交集:

# Cannot use AES and above for SunCC 12.2
ALLOWED_CXXFLAGS="-D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__"
# New processor, needs to be filtered due to old compiler
SUNCC_CXXFLAGS="-D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__ -D__AES__ -D__PCLMUL__ __AVX__ ..."
Run Code Online (Sandbox Code Playgroud)

我已经看到了许多关于awk 匹配(和非匹配)正则表达式和行的问题和答案。但是我需要根据一行中的标记进行过滤。

我尝试了以下方法,但没有产生预期的结果:

$ echo "-D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__ -D__AES__ -D__PCLMUL__" | \
  nawk '!/(-D__SSE2__|-D__SSE3__|-D__SSSE3__)/'
$
Run Code Online (Sandbox Code Playgroud)

另一个转折点:这是 Solaris,因此这些工具没有 GNU 工具中的很多选项。这是我尝试使用 awk 而不是 sed 或 grep 的原因之一。

如何过滤掉与我的令牌集不匹配的令牌?

Joh*_*024 7

要仅选择 SSE 标志,请尝试:

awk '/SSE/' ORS=' ' RS=' '
Run Code Online (Sandbox Code Playgroud)

这里的关键是将输入和输出的记录分隔符设置为空格。这样,每个选项都会被分别接受或拒绝。

例如:

$ 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__ 
Run Code Online (Sandbox Code Playgroud)

SSE这里似乎是一场足够紧密的比赛。如果不是,我们可以更具体:

$ 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__ 
Run Code Online (Sandbox Code Playgroud)

替代方案:不包括 SSE 和 AES

$ echo "$SUNCC_CXXFLAGS" | nawk '!/SSE|AES/' ORS=' ' RS=' '
-D__PCLMUL__ ...
Run Code Online (Sandbox Code Playgroud)

保留匹配SSE 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=sse3
Run Code Online (Sandbox Code Playgroud)

这里的变化是我们/SSE//SSE|sse/. 因为垂直条,|指逻辑或,此匹配任一SSEsse