这是一种延续awk 并丢弃字符串中不匹配的标记?我正在使用 Awk 过滤源自 CPU 功能的不需要的编译器标志(SunCC 12.2 无法处理与 SunCC 12.5 相同的标志)。过滤器生成的结果CXXFLAGS
会导致 SunCC 12.2 下的编译错误:
/opt/solstudio12.2/bin/CC -DDEBUG -g -xO0 -D__SSE2__ -D__SSE3__ -D__SSSE3__
usage: usage: CCCC [ options ] files. Use 'CC -flags' for details
[ options ] files. Use 'CC -flags' for details
usage: CC [ options ] files. Use 'CC -flags' for details
usage: CC [ options ] files. Use 'CC -flags' for details
m64 -KPIC -template=no%extdef -w -erroff=wvarhidemem -erroff=voidretw -c cryptlib.cpp
正在发生的事情是,Awk 正在生成-D__SSE2__ -D__SSE3__ -D__SSSE3__ + \n
.因此它CXXLAGS
被分成两行,这导致 GNUmake 的结果如下:
/opt/solstudio12.2/bin/CC -DDEBUG -g -xO0 -D__SSE2__ -D__SSE3__ -D__SSSE3__
-m64 -KPIC -template=no%extdef -w -erroff=wvarhidemem -erroff=voidretw -c cryptlib.cpp
当我调试驱动它的 Bash 脚本时。如果我正确解析输出,第 1012 行和第 1014 行似乎有问题。
$ PS4='Line ${LINENO}: ' bash -x ./cryptest.sh
...
Line 1005: SUNCC_CXXFLAGS='-D__SSE2__ -D__SSE3__ -D__SSSE3__'
Line 1008: echo 'PLATFORM_CXXFLAGS: -D__SSE2__' -D__SSE3__ -D__SSSE3__
PLATFORM_CXXFLAGS: -D__SSE2__ -D__SSE3__ -D__SSSE3__
Line 1009: echo 'SUNCC_CXXFLAGS: -D__SSE2__ -D__SSE3__ -D__SSSE3__'
SUNCC_CXXFLAGS: -D__SSE2__ -D__SSE3__ -D__SSSE3__
LLine 1012: echo '-D__SSE2__ -D__SSE3__ -D__SSSE3__'
LLine 1012: /usr/gnu/bin/awk /SSE/ 'ORS= ' 'RS= '
Line 1012: SUNCC_SSE_CXXFLAGS='-D__SSE2__ -D__SSE3__ -D__SSSE3__
'
Line 1014: echo 'SUNCC_SSE_CXXFLAGS: -D__SSE2__ -D__SSE3__ -D__SSSE3__
'
SUNCC_SSE_CXXFLAGS: -D__SSE2__ -D__SSE3__ -D__SSSE3__
Line 1020: [[ -e /opt/solstudio12.2/bin/CC ]]
这是相应的 Bash 源代码。我相信罪犯是第 1012 行SUNCC_SSE_CXXFLAGS=$(echo "$SUNCC_CXXFLAGS" | "$AWK" '/SSE/' ORS=' ' RS=' ')
。
1003 # If PLATFORM_CXXFLAGS is for SunCC, then use them
1004 if [[ ("$SUNCC_121_OR_ABOVE" -ne "0") ]]; then
1005 SUNCC_CXXFLAGS="${PLATFORM_CXXFLAGS[@]}"
1006 fi
1007
1008 echo "PLATFORM_CXXFLAGS: ${PLATFORM_CXXFLAGS[@]}"
1009 echo "SUNCC_CXXFLAGS: ${SUNCC_CXXFLAGS[@]}"
1010
1011 # Sun Studio 12.3 and below workaround, http://github.com/weidai11/cryptopp/issues/228
1012 SUNCC_SSE_CXXFLAGS=$(echo "$SUNCC_CXXFLAGS" | "$AWK" '/SSE/' ORS=' ' RS=' ')
1013
1014 echo "SUNCC_SSE_CXXFLAGS: ${SUNCC_SSE_CXXFLAGS[@]}"
...
1018 ############################################
1019 # Sun Studio 12.2
1020 if [[ (-e "/opt/solstudio12.2/bin/CC") ]]; then
我的问题是,在 Solaris 下 Awk'ing 数组时如何抑制换行?
以下是脚本调用 make 的方式。该脚本可以在以下位置找到:cryptest.sh
。它是一个怪物,但有问题的行在 2880 左右(上面的第 1000 行是简化的测试用例,以帮助隔离事物)。
CXXFLAGS="-DDEBUG -g -xO0 ${SUNCC_SSE_CXXFLAGS[@]}"
CXX="/opt/solstudio12.2/bin/CC" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
这是如何PLATFORM_CXXFLAGS
形成的。这对于我们的源代码来说是必需的,因为代码路径是根据 GCC 定义激活的(但 SunCC 没有定义它们)。
if [[ ("$IS_SOLARIS" -ne "0") && ("$SUNCC_121_OR_ABOVE" -ne "0") ]]; then
ISAINFO=$(isainfo -v 2>/dev/null)
if [[ ($(echo "$ISAINFO" | "$GREP" -c "sse2") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__SSE2__"); fi
if [[ ($(echo "$ISAINFO" | "$GREP" -c "sse3") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__SSE3__"); fi
if [[ ($(echo "$ISAINFO" | "$GREP" -c "ssse3") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__SSSE3__"); fi
if [[ ($(echo "$ISAINFO" | "$GREP" -c "sse4.1") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__SSE4_1__"); fi
if [[ ($(echo "$ISAINFO" | "$GREP" -c "sse4.2") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__SSE4_2__"); fi
if [[ ($(echo "$ISAINFO" | "$GREP" -c "aes") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__AES__"); fi
if [[ ($(echo "$ISAINFO" | "$GREP" -c "pclmulqdq") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__PCLMUL__"); fi
if [[ ($(echo "$ISAINFO" | "$GREP" -c "rdrand") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__RDRND__"); fi
if [[ ($(echo "$ISAINFO" | "$GREP" -c "rdseed") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__RDSEED__"); fi
if [[ ($(echo "$ISAINFO" | "$GREP" -c "avx") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__AVX__"); fi
if [[ ($(echo "$ISAINFO" | "$GREP" -c "avx2") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__AVX2__"); fi
if [[ ($(echo "$ISAINFO" | "$GREP" -c "bmi") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__BMI__"); fi
if [[ ($(echo "$ISAINFO" | "$GREP" -c "bmi2") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__BMI2__"); fi
fi
答案1
在:
echo '-D__SSE2__ -D__SSE3__ -D__SSSE3__' | awk /SSE/ RS=' ' ORS=' '
你正在喂食-D__SSE2__ -D__SSE3__ -D__SSSE3__<newline>
(awk
添加echo
换行符)。
对于RS=' '
,这意味着 3 条记录:-D__SSE2__
、-D__SSE3__
和-D__SSSE3__<newline>
。所有匹配的/SSE/
so 都会被打印出来,后跟输出记录分隔符 ( ORS=' '
)。对于第三个,那就是-D__SSSE3__<newline><space>
<newline>
所以在这里,您希望首先不输出:
printf %s '-D__SSE2__ -D__SSE3__ -D__SSSE3__' | awk...
或者添加一个额外的空格,这样就<newline>
可以有自己的记录(不匹配/SSE/
):
echo '-D__SSE2__ -D__SSE3__ -D__SSSE3__ ' | awk...
或者,由于您使用的是 GNUawk
而不是 Solaris,请将任何空格字符序列作为记录分隔符:
echo -D__SSE2__ -D__SSE3__ -D__SSSE3__ | gawk -v 'RS=[[:space:]]+' ...