![Awk 배열 시 줄 바꿈을 비활성화합니다.](https://linux55.com/image/93055/Awk%20%EB%B0%B0%EC%97%B4%20%EC%8B%9C%20%EC%A4%84%20%EB%B0%94%EA%BF%88%EC%9D%84%20%EB%B9%84%ED%99%9C%EC%84%B1%ED%99%94%ED%95%A9%EB%8B%88%EB%8B%A4..png)
이것은 연속이다문자열에서 일치하지 않는 토큰을 삭제하시겠습니까?저는 CPU 기능에서 발생하는 원치 않는 컴파일러 플래그를 필터링하기 위해 Awk를 사용하고 있습니다(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할 때 어떻게 줄바꿈을 억제할 수 있느냐는 것입니다.
스크립트 호출이 수행되는 방법은 다음과 같습니다. 스크립트는 다음에서 찾을 수 있습니다.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=' '
이는 -D__SSE2__
, -D__SSE3__
및 3개의 레코드를 의미합니다 -D__SSSE3__<newline>
. 일치하는 모든 항목 /SSE/
이 인쇄되고 그 뒤에 출력 레코드 구분 기호( 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...
또는 Solaris가 아닌 GNU를 사용하고 있으므로 awk
공백 문자 시퀀스를 레코드 구분 기호로 사용하십시오.
echo -D__SSE2__ -D__SSE3__ -D__SSSE3__ | gawk -v 'RS=[[:space:]]+' ...