使用 ${VARNAME//pattern/} 方式从字符串中删除数字和符号的组合

使用 ${VARNAME//pattern/} 方式从字符串中删除数字和符号的组合

我正在尝试编写一个脚本,使用两个不同的可执行文件对 valgrind 的输出执行 diff,但是每行开头的进程 ID 都在我的 diff 输出中乱七八糟。我正在尝试使用 bash 命令删除它,但似乎无法成功。

到目前为止,这是我的代码:

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

这会删除 VG_MY 中的所有数字,与此相同:

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

我尝试以多种方式添加 == 部分,但没有成功。我最接近的是:

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

这会从 valgrind 输出中删除所有数字 AND '='。我需要弄清楚我缺少什么,以便仅从 valgrind 输出中删除“=”括起来的数字,如下所示: ==123456== 。

编辑: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)

答案1

kshor bash -O extglob(或shopt -s extglobbash脚本中的之后)或zsh -o kshglob(或set -o kshglob在脚本中的之后zsh):

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

+(...)是一个 ksh 扩展 glob,类似于+扩展 regexp 运算符。+(x)匹配一个或多个xs。

因此,上面删除了所有由一个或多个=s 后跟一个或多个十进制数字后跟一个或多个=s 组成的序列,就像sed -E 's/=+[0-9]+=+//g'1 那样。

并不是说它无法删除 456==内部,==123====456==因为第一次替换会删除==123====留下与模式不匹配的东西。为了能够删除它们,您可以将其更改为:

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

(喜欢sed -E 's/=+[0-9][0-9=]*=//g'

Withzsh自己的扩展 glob ( zsh -o extendedglob):#相当于 ERE*##ERE +(以及(#c1,3){1,3}。所以,你可以这样做:

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

1 请注意,虽然有几个sed实现支持-E扩展正则表达式,但它还不是标准的,您偶尔会发现一些不支持它的实现。有了这些,您可以跳过-E并用作\{1,\}BRE 替代品+(或使用==*代替=+)。

答案2

==94953==只需在比较输出之前删除每行开头的 :

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 

或者,它允许您保存未修改的输出,并且仅在运行时修改它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 )

相关内容