我无法获得字符串工具来提供我需要的东西(由于我的无知)。我有一个基于 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__ ..."
该字符串非常适合 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__ ..."
我看过很多问题和答案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__)/'
$
另一个变化:这是 Solaris,因此这些工具没有 GNU 工具中的很多选项。这是我尝试 awk 而不是 sed 或 grep 的原因之一。
如何过滤掉与我的标记集不匹配的标记?
答案1
要仅选择 SSE 标志,请尝试:
awk '/SSE/' ORS=' ' RS=' '
这里的关键是将输入和输出的记录分隔符设置为空格。这样,每个选项都会被单独接受或拒绝。
例如:
$ 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
这里的匹配似乎足够紧密。如果不是,我们可以更具体:
$ 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__
替代方案:排除 SSE 和 AES
$ echo "$SUNCC_CXXFLAGS" | nawk '!/SSE|AES/' ORS=' ' RS=' '
-D__PCLMUL__ ...
保留匹配的选项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
这里的变化是我们将正则表达式替换/SSE/
为/SSE|sse/
.因为竖线 ,|
表示逻辑或,所以它匹配SSE
或sse
。