Remove uma combinação de números e símbolos de uma string usando o caminho $ {VARNAME // pattern /}

2

Eu estou tentando escrever um script que realiza diff na saída de valgrind usando dois executáveis diferentes, mas o ID do processo no início de cada linha está sujando minha saída de diff. Eu estou tentando removê-lo usando comandos bash, mas não consigo ter sucesso.

Aqui está meu código até agora:

VG_MY=$((valgrind --leak-check=full ./executable < inputfile) 2>&1)
VG_MY=${VG_MY//[0-9]/}

isso remove todos os dígitos de VG_MY, da mesma forma:

VG_MY="${VG_MY//[[:digit:]]/}"

Eu tentei adicionar as partes == de várias maneiras, mas nenhuma funcionou. O mais próximo que eu tenho é:

VG_MY="${VG_MY//[==[:digit:]==]/}"

Que remove todos os dígitos AND '=' da saída do valgrind. Eu preciso descobrir o que eu estou perdendo, a fim de remover apenas os números entre '=' assim: == 123456 == da saída valgrind.

EDITAR: uma amostra de saída valgrind:

==94953== Memcheck, a memory error detector
==94953== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==94953== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==94953== Command: ./executable
==94953== 
==94953== 
==94953== HEAP SUMMARY:
==94953==     in use at exit: 0 bytes in 0 blocks
==94953==   total heap usage: 13 allocs, 13 frees, 232 bytes allocated
==94953== 
==94953== All heap blocks were freed -- no leaks are possible
==94953== 
==94953== For counts of detected and suppressed errors, rerun with: -v
==94953== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 6)
    
por Yekhezkel Yovel 07.05.2018 / 15:16

2 respostas

7

Com ksh ou bash -O extglob (ou depois de shopt -s extglob em um script bash ) ou zsh -o kshglob (ou depois de set -o kshglob em um script zsh ):

VG_MY=${VG_MY//+(=)+([0-9])+(=)/}

O +(...) é um glob estendido ksh semelhante ao operador regexp estendido + . +(x) corresponde a um ou mais x s.

Portanto, o texto acima remove todas as seqüências de um ou mais = s seguidas por um ou mais dígitos decimais seguidos por um ou mais = s como sed -E 's/=+[0-9]+=+//g' ¹.

Não que seja possível remover 456== dentro de ==123====456== , pois a primeira substituição removeria ==123==== deixando algo que não corresponde ao padrão. Para poder removê-los, você pode alterá-lo para:

VG_MY=${VG_MY//+(=)[0-9]*([0-9=])=/}

(como sed -E 's/=+[0-9][0-9=]*=//g' )

Com as próprias globs estendidas de zsh ( zsh -o extendedglob ): # é o equivalente a ERE * e ## de ERE + (e (#c1,3) de {1,3} ). Então, você pode fazer isso:

set -o extendedglob
VG_MY=${VG_MY//=##[0-9]##=##/}

¹ Observe que, embora várias implementações de sed suportem -E para regexps estendidas, ela ainda não é padrão, e você pode ocasionalmente encontrar algumas implementações que não a suportam. Com esses, você pode ignorar -E e usar \{1,\} como substituto do BRE para + (ou usar ==* em vez de =+ ).

    
por 07.05.2018 / 15:26
4

Basta excluir o ==94953== no início de cada linha antes de comparar as saídas:

valgrind --leak-check=full ./executable1 <inputfile 2>&1 | sed 's/^==[0-9]*== //' >output1
valgrind --leak-check=full ./executable2 <inputfile 2>&1 | sed 's/^==[0-9]*== //' >output2

diff -u output1 output2 

Como alternativa, você pode salvar a saída não modificada e apenas modificá-la ao executar o diff

valgrind --leak-check=full ./executable1 <inputfile >output1 2>&1
valgrind --leak-check=full ./executable2 <inputfile >output2 2>&1

diff -u <( sed 's/^==[0-9]*== //' <output1 ) <( sed 's/^==[0-9]*== //' <output2 )
    
por 07.05.2018 / 16:32