Regex 具有多个匹配项和条件的sed正则表达式

Regex 具有多个匹配项和条件的sed正则表达式,regex,sed,perl,Regex,Sed,Perl,我想转换如下字符串: abc=123.24|127.9|2891;xyz;hgy 致: 这很接近: echo "abc=123.24|127.9|2891;xyz;hgy" | sed -r 's/(=)([0-9.]+)\|/\1\2,/g' 但返回: abc=123.24,127.9|2891;xyz;hgy 如果条形分隔数字的数量是可变的,我如何以类似的方式处理其余的数字 澄清: 我讨厌人们不告诉我问题的全貌,但我上面的原始描述就是这样。小示例嵌入在一个更大的行中,其中包含“|”分隔

我想转换如下字符串:

abc=123.24|127.9|2891;xyz;hgy
致:

这很接近:

echo "abc=123.24|127.9|2891;xyz;hgy" | sed -r 's/(=)([0-9.]+)\|/\1\2,/g'
但返回:

abc=123.24,127.9|2891;xyz;hgy
如果条形分隔数字的数量是可变的,我如何以类似的方式处理其余的数字

澄清

我讨厌人们不告诉我问题的全貌,但我上面的原始描述就是这样。小示例嵌入在一个更大的行中,其中包含“|”分隔文本。我只想将等号后面的数字之间的“|”替换为“,”。以下是一整行的示例:

chr1    69511   rs75062661  A   G   .   QSS_ref ASP;BaseCounts=375,3,118,4;CAF=[0.348,0.652];COMMON=1;EFF=NON_SYNONYMOUS_CODING(MODERATE|MISSENSE|Aca/Gca|T141A|305|OR4F5|protein_coding|CODING|ENST00000335137|1|1);GNO;HRun=0;HaplotypeScore=0.0000;KGPROD;KGPhase1;LowMQ=0.0280,0.0580,500;MQ=49.32;MQ0=14;MSigDb=ACEVEDO_METHYLATED_IN_LIVER_CANCER_DN,KEGG_OLFACTORY_TRANSDUCTION,REACTOME_GPCR_DOWNSTREAM_SIGNALING,REACTOME_OLFACTORY_SIGNALING_PATHWAY,REACTOME_SIGNALING_BY_GPCR,chr1p36;NORMALT=86;NORMREF=228;NSM;NT=het;OTHERKG;QSS=8;QSS_NT=6;REF;RS=75062661;RSPOS=69511;S3D;SAO=0;SGT=AG->AG;SOMATIC;SSR=0;TQSS=1;TQSS_NT=2;TUMALT=15;TUMREF=227;TUMVAF=0.06198347107438017;TUMVARFRACTION=0.1485148514851485;VC=SNV;VLD;VP=0x050200000a05140116000100;WGT=1;dbNSFP_1000Gp1_AC=1424;dbNSFP_1000Gp1_AF=0.652014652014652;dbNSFP_1000Gp1_AFR_AC=162;dbNSFP_1000Gp1_AFR_AF=0.32926829268292684;dbNSFP_1000Gp1_AMR_AC=235;dbNSFP_1000Gp1_AMR_AF=0.649171270718232;dbNSFP_1000Gp1_ASN_AC=500;dbNSFP_1000Gp1_ASN_AF=0.8741258741258742;dbNSFP_1000Gp1_EUR_AC=527;dbNSFP_1000Gp1_EUR_AF=0.6952506596306068;dbNSFP_29way_logOdds=4.1978;dbNSFP_29way_pi=0.1516:0.0:0.6258:0.2226;dbNSFP_ESP6500_AA_AF=0.544101;dbNSFP_ESP6500_EA_AF=0.887429;dbNSFP_Ensembl_geneid=ENSG00000186092;dbNSFP_Ensembl_transcriptid=ENST00000534990|ENST00000335137;dbNSFP_FATHMM_score=0.51;dbNSFP_GERP++_NR=2.31;dbNSFP_GERP++_RS=1.15;dbNSFP_Interpro_domain=GPCR|_rhodopsin-like_superfamily_(1)|;dbNSFP_LRT_Omega=0.000000;dbNSFP_LRT_pred=N;dbNSFP_LRT_score=0.000427;dbNSFP_MutationAssessor_pred=neutral;dbNSFP_MutationAssessor_score=-1.295;dbNSFP_MutationTaster_pred=N;dbNSFP_MutationTaster_score=0.000162;dbNSFP_Polyphen2_HDIV_pred=B;dbNSFP_Polyphen2_HVAR_pred=B;dbNSFP_SIFT_score=0.950000;dbNSFP_Uniprot_aapos=141;dbNSFP_Uniprot_acc=Q8NH21;dbNSFP_Uniprot_id=OR4F5_HUMAN;dbNSFP_aaalt=A;dbNSFP_aapos=189|141;dbNSFP_aaref=T;dbNSFP_cds_strand=+;dbNSFP_codonpos=1;dbNSFP_fold-degenerate=0;dbNSFP_phyloP=0.267000;dbNSFP_refcodon=ACA;dbSNPBuildID=131   AU:CU:DP:FDP:GU:SDP:SUBDP:TU    228,232:3,3:322:4:86,109:0:0:1,2    227,228:0,0:244:1:15,16:0:0:1,2
该行中的替换内容为字符串:

dbNSFP_aapos=189|141
与:

为什么不:

sed 's/|/,/g'


kent$ echo "abc=123.24|127.9|2891;xyz;hgy"|sed 's/|/,/g'
abc=123.24,127.9,2891;xyz;hgy
为什么不:

sed 's/|/,/g'


kent$ echo "abc=123.24|127.9|2891;xyz;hgy"|sed 's/|/,/g'
abc=123.24,127.9,2891;xyz;hgy

假设分号是字段分隔符,那么

tr `;\n' '\n;' | sed '/=[0-9.|]*$/s/|/,/g' | tr '\n;' ';\n'
这有一个严重的缺陷;对于一行中的第一个和最后一个字段,它以奇怪的方式失败。如果你无法忍受,不妨尝试一下:

awk -F ';' '{ for(i=1; i<=NF; ++i) if ($i ~ /=([0-9.]+\|)+[0-9.]+$/) gsub(/\|/,",",$i); print }'

awk-F';“”{for(i=1;i假设分号是字段分隔符,那么

tr `;\n' '\n;' | sed '/=[0-9.|]*$/s/|/,/g' | tr '\n;' ';\n'
这有一个严重的缺陷;它在一行的第一个和最后一个字段中以奇怪的方式失败。如果你不能接受这一点,可以尝试以下方法:

awk -F ';' '{ for(i=1; i<=NF; ++i) if ($i ~ /=([0-9.]+\|)+[0-9.]+$/) gsub(/\|/,",",$i); print }'
awk-F';''{for(i=1;i使用
tr

echo "abc=123.24|127.9|2891;xyz;hgy" | tr \| ,
abc=123.24,127.9,2891;xyz;hgy
使用
tr

echo "abc=123.24|127.9|2891;xyz;hgy" | tr \| ,
abc=123.24,127.9,2891;xyz;hgy

或者,您可以尝试使用及其评估标志:

echo "..." | perl -pe 's{=([\d.|]+)}{"=" . (join ",", split /\|/, $1)}eg'

它在等号后搜索字符串,用
|
将其拆分,并用逗号将其连接。

作为替代方法,您可以尝试使用及其求值标志:

echo "..." | perl -pe 's{=([\d.|]+)}{"=" . (join ",", split /\|/, $1)}eg'

它在等号后搜索字符串,用
|
将其拆分,并用逗号将其连接起来。

不使用perl,您可以使用

input="abc=123;def=hello123test;dbNSFP_aapos=189|141|142;dbNSFP_aaref=T;another=test|hello;"

sed -r 's/(.*=)([0-9.]+\|)+(.*)/\1'$(sed -r 's/(.*=)([0-9.]+\|)+(.*)/\2/' <<< $input | tr '|' ,)'\3/' <<< $input

不使用您可以使用的perl替换

input="abc=123;def=hello123test;dbNSFP_aapos=189|141|142;dbNSFP_aaref=T;another=test|hello;"

sed -r 's/(.*=)([0-9.]+\|)+(.*)/\1'$(sed -r 's/(.*=)([0-9.]+\|)+(.*)/\2/' <<< $input | tr '|' ,)'\3/' <<< $input

替换
为什么不呢?因为当涉及正则表达式时,人们往往认为过于复杂:)+1因为你比我快了几秒钟,或者因为OP没有给你完整的问题——对不起。请看上面的说明。@seandavi你能给出一个完整的示例行吗?@Kent:在原始帖子中添加了一个完整的示例行。为什么不呢?因为当涉及正则表达式时,人们倾向于认为过于复杂:)+1因为你比我快了几秒钟,或者因为OP没有给你完整的问题——对不起。请看上面的澄清。@seandavi你能给出一个完整的示例行吗?@Kent:在原来的帖子中添加了完整的示例行。你是否坚持使用
sed
?不。但是,我尝试做的是“内联”通过管道以避免在工作流中跟踪另一个脚本。您是否坚持使用
sed
?没有。但是,我尝试通过管道“内联”以避免在工作流中跟踪另一个脚本。您在比较条件中错过了结尾“/”。
($I~/=([0-9.]+\\124;)+[0-9.]+$/)
您错过了结尾“/”在比较条件下。
($i~/=([0-9.]+\\\|)+[0-9.]+$/)