Awk e descartando tokens não correspondentes em uma string?

3

Estou tendo problemas para obter uma ferramenta de string para fornecer o que preciso (devido à minha ignorância). Eu tenho uma string baseada em recursos da CPU. A string muda conforme diferentes processadores oferecem recursos diferentes :

# 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__ ..."

A string funciona muito bem para o Sun Studio 12.3 e superior. Para o Sun Studio 12.2 e inferior, só posso usar SSE2, SSE3, SSSE3, SSE4.1 e SSE4.2 . AES e acima define causa um erro obscuro , então eles devem ser filtrados para fora das bandeiras .

Por outro lado, preciso da interseção dos dois conjuntos:

# 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__ ..."

Eu vi várias perguntas e respostas com regexes e linhas do awk correspondentes (e não correspondentes) . Mas preciso filtrar com base em tokens em uma única linha.

Eu tentei o seguinte, que não produz os resultados esperados:

$ echo "-D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__ -D__AES__ -D__PCLMUL__" | \
  nawk '!/(-D__SSE2__|-D__SSE3__|-D__SSSE3__)/'
$

Outra reviravolta: isso é o Solaris, então as ferramentas não têm muitas opções presentes nas ferramentas GNU. É uma das razões que eu tentei awk em vez de sed ou grep.

Como posso filtrar os tokens que não correspondem ao meu conjunto de tokens?

    
por Community 15.07.2016 / 22:51

1 resposta

7

Para selecionar apenas os sinalizadores SSE, tente:

awk '/SSE/' ORS=' ' RS=' '

A principal coisa aqui é definir os separadores de registro em entrada e saída para um espaço. Dessa forma, cada opção é aceita ou rejeitada separadamente.

Por exemplo:

$ 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 parece ser uma correspondência muito boa aqui. Se não for, podemos ser mais específicos:

$ 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__ 

Alternativa: excluindo SSE e AES

$ echo "$SUNCC_CXXFLAGS" | nawk '!/SSE|AES/' ORS=' ' RS=' '
-D__PCLMUL__ ...

Manter as opções que correspondem a SSE ou 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

A alteração aqui é que substituímos o regex /SSE/ por /SSE|sse/ . Como a barra vertical, | , significa lógica-or, isso corresponde a SSE ou sse .

    
por 15.07.2016 / 23:08