删除模式之间的逗号

Remove commas between patterns

提问人:Geomicro 提问时间:11/2/2023 最后编辑:Timur ShtatlandGeomicro 更新时间:11/15/2023 访问量:76

问:

我正在尝试在我的文本文件中使用 .例如,我的理想输出是 。sedK01810,GPI,,pgi;,glucose-6-phosphate,isomerase,[EC:5.3.1.9]K01810,GPI,,pgi; glucose-6-phosphate isomerase [EC:5.3.1.9]

我试过了,但这并没有改变任何事情。sed 's/;\(.*\)\[/;\1[/g' myfile.txt > newfile

myfile.txt:

09100,Metabolism
09101,Carbohydrate,metabolism
00010,Glycolysis,/,Gluconeogenesis,[PATH:ko00010]
K00844,HK;,hexokinase,[EC:2.7.1.1]
K12407,GCK;,glucokinase,[EC:2.7.1.2]
K00845,glk;,glucokinase,[EC:2.7.1.2]
K25026,glk;,glucokinase,[EC:2.7.1.2]
K01810,GPI,,pgi;,glucose-6-phosphate,isomerase,[EC:5.3.1.9]
K06859,pgi1;,glucose-6-phosphate,isomerase,,archaeal,[EC:5.3.1.9]
K13810,tal-pgi;,transaldolase,/,glucose-6-phosphate,isomerase,[EC:2.2.1.2,5.3.1.9]
K15916,pgi-pmi;,glucose/mannose-6-phosphate,isomerase,[EC:5.3.1.9,5.3.1.8]
K24182,PFK9;,6-phosphofructokinase,[EC:2.7.1.11]
K00850,pfkA,,PFK;,6-phosphofructokinase,1,[EC:2.7.1.11]
K16370,pfkB;,6-phosphofructokinase,2,[EC:2.7.1.11]
正则表达式 SED

评论


答:

2赞 jhnc 11/2/2023 #1
sed '
    # skip lines that do not match
    /^\(.*\)\(;.*\[\)\(.*\)$/ ! b

    # save a copy of original line
    h

    # extract prefix/suffix
    s//\1\n\3/

    # save them, restore original line
    x

    # extract part to change
    s//\2/

    # do the substitution
    y/,/ /

    # append prefix/suffix
    G

    # rearrange
    s/^\([^\n]*\)\n\([^\n]*\)\n/\2\1/
    
' myfile.txt >newfile

注意:为了便于移植,替换时需要转义的文字换行符(某些版本的 sed 仅视为):\nn

    # ...

    # extract prefix/suffix
    s//\1\
\3/

    # ...

评论

0赞 Geomicro 11/2/2023
哇,非常感谢你的解释!谢谢你,善良的陌生人。
2赞 jhnc 11/2/2023
Perl 更短一些:perl -ple 's:;.*\[:y/,/ /r:e' myfile.txt >newfile
0赞 Geomicro 11/2/2023
谢谢。我现在意识到我有一些不包含“[”的行,但我仍然需要删除“;”之后的所有逗号。
1赞 jhnc 11/2/2023
问题中的前三个输入不包含 .您可以调整我的正则表达式,以使用您需要的任何规则将行拆分为前缀/部分以更改/后缀。我只能猜测这些规则应该是什么;
0赞 jhnc 11/4/2023
哎呀。错误的变量:perl -pe 's:;.*\[:$&=~y/,/ /r:e' ...
2赞 potong 11/2/2023 #2

这可能对你有用 (GNU sed):

sed -E ':a;s/(;[^,[]*),/\1 /;ta' file

匹配以 a 开头且不包含 或 的任意连续字符,后跟 a,并将 替换为空格。;[,,,

如果替换成功,请重复直到失败。

1赞 Timur Shtatland 11/2/2023 #3

使用这个 Perl 单行代码:

perl -pe 's{(;[^;\[]+)}{ do { $s = $1; $s =~ tr/,/ /; $s } }e; ' infile > outfile

或就地更改它:

perl -i.bak -pe 's{(;[^;\[]+)}{ do { $s = $1; $s =~ tr/,/ /; $s } }e; ' infile

Perl 单行代码使用以下命令行标志: :
告诉 Perl 以内联方式查找代码,而不是在文件中查找代码。
:一次循环一行输入,默认分配给输入。在每次循环迭代后添加。
:就地编辑输入文件(覆盖输入文件)。在覆盖之前,通过在其名称后附加扩展名来保存原始文件的备份副本。如果您想跳过写入备份文件,只需使用并跳过扩展名即可。
-e-p$_print $_-i.bak.bak-i

正则表达式使用以下修饰符: :
作为表达式计算
/eREPLACEMENTs/PATTERN/REPLACEMENT/

s{PATTERN}{EXPRESSION}:替换为 。
:字面意思,后跟除 或 之外的任何字符的 1 个或多个字符(请注意,必须转义:。括号将匹配项捕获到变量 中。
:重新分配给 ,然后更改所有出现的 to(空格)。该块返回最后一个表达式,即这些更改后的变量。
PATTERNEXPRESSION(;[^;\[]+);;[\[$1do { $s = $1; $s =~ tr/,/ /; $s }$1$s, $s

另请参阅:

1赞 Ed Morton 11/3/2023 #4

将 GNU awk 用于第 3 个参数:match()

$ awk 'match($0,/(.*;)([^[]+)(\[.*)/,a) {
    $0 = a[1] gensub(/,/," ","g",a[2]) a[3]
} 1' file
09100,Metabolism
09101,Carbohydrate,metabolism
00010,Glycolysis,/,Gluconeogenesis,[PATH:ko00010]
K00844,HK; hexokinase [EC:2.7.1.1]
K12407,GCK; glucokinase [EC:2.7.1.2]
K00845,glk; glucokinase [EC:2.7.1.2]
K25026,glk; glucokinase [EC:2.7.1.2]
K01810,GPI,,pgi; glucose-6-phosphate isomerase [EC:5.3.1.9]
K06859,pgi1; glucose-6-phosphate isomerase  archaeal [EC:5.3.1.9]
K13810,tal-pgi; transaldolase / glucose-6-phosphate isomerase [EC:2.2.1.2,5.3.1.9]
K15916,pgi-pmi; glucose/mannose-6-phosphate isomerase [EC:5.3.1.9,5.3.1.8]
K24182,PFK9; 6-phosphofructokinase [EC:2.7.1.11]
K00850,pfkA,,PFK; 6-phosphofructokinase 1 [EC:2.7.1.11]
K16370,pfkB; 6-phosphofructokinase 2 [EC:2.7.1.11]

或者,您可以使用任何awk执行相同的操作:

awk 'match($0,/(.*;)([^[]+)(\[.*)/) {
    tgt = substr($0,RSTART,RLENGTH); gsub(/,/," ",tgt)
    $0 = substr($0,1,RSTART-1) tgt substr($0,RSTART+RLENGTH)
} 1' file