我可以使用sed替换所选字符,例如H => X
,1 => 2
,但首先向前搜索,以便不替换第一组中的字符。
示例数据:
"Hello World";"Number 1 is there";"tH1s-Has,1,HHunKnownData";
sed
之后应如何:
"Hello World";"Number 1 is there";"tX2s-Xas,2,XXunKnownData";
我尝试过:
没什么,我会尝试,但我所知道的关于sed表达式的一切似乎都是错误的。
好的,我试图捕获([^;]+)
和“跳过”(使用'\ 1 \ 2'...... 让我们回来)第一组以;
分隔,这工作正常,但后来出现问题,如果我使用捕获我需要选择整个组,如果我不使用捕获,我将丢失数据。
答案 0 :(得分:1)
如果awk对你没问题:
awk -F";" '{gsub("H","X",$3);gsub("1","2",$3);}1' OFS=";" file
使用-F,文件以分号分隔为分隔符,因此现在第3个字段($ 3)是我们感兴趣的。 gsub函数用第3个字段中的X替换所有出现的H,再次1到2。
1是打印每一行。
答案 1 :(得分:1)
<强> [UPDATE] 强>
(我刚才意识到它可能会更短.Perl有一个自动分割模式):
$F[2] =~ s/H/X/g; $F[2] =~ s/1/2/g; $_=join(";",@F)
Perl的特别可读性并不为人所知,但在这种情况下,我怀疑使用sed
获得的最佳效果可能不如Perl那么清晰:
echo '"Hello World";"Number 1 is there";"tH1s-Has,1,HHunKnownData";' |
perl -F';' -ape '$F[2] =~ s/H/X/g; $F[2] =~ s/1/2/g; $_=join(";",@F)'
拆开Perl代码:
# your groups are in @F, accessed as $F[$i]
$F[2] =~ s/H/X/g; # Do whatever you want with your chosen (Nth) group.
$F[2] =~ s/1/2/g;
$_ = join(";", @F) # Put them back together.
perl -pe
与sed
类似。 (有点。)
和perl -F';' -ape
表示使用自动拆分(-a
)并将字段分隔符设置为';'
。然后,您可以通过$F[i]
访问您的论坛 - 因此它的工作方式也类似于awk
。
所以它也会像perl -F';' -ape '/*your code*/' < inputfile
我知道您要求sed
解决方案 - 我经常发现自己会转换为Perl(虽然我仍然喜欢sed
),但我会选择单行。
答案 2 :(得分:1)
sed
可以实现这一点,但有点单调乏味。要在字段编号$FIELD
进行翻译,您可以使用以下内容:
sed 's/\(\([^;]*;\)\{'$((FIELD-1))'\}\)\([^;]*;\)/\1\n\3\n/;h;s/[^\n]*\n\([^\n]*\).*/\1/;y/H1/X2/;G;s/\([^\n]*\)\n\([^\n]*\)\n\([^\n]*\)\n\([^\n]*\)/\2\1\4/'
或者,使用GNU sed
减少括号数:
sed -r 's/(([^;]*;){'$((FIELD-1))'})([^;]*;)/\1\n\3\n/;h;s/[^\n]*\n([^\n]*).*/\1/;y/H1/X2/;G;s/([^\n]*)\n([^\n]*)\n([^\n]*)\n([^\n]*)/\2\1\4/'
示例:
$ FIELD=3
$ echo '"Hello World";"Number 1 is there";"tH1s-Has,1,HHunKnownData";' | sed -r 's/(([^;]*;){'$((FIELD-1))'})([^;]*;)/\1\n\3\n/;h;s/[^\n]*\n([^\n]*).*/\1/;y/H1/X2/;G;s/([^\n]*)\n([^\n]*)\n([^\n]*)\n([^\n]*)/\2\1\4/'
"Hello World";"Number 1 is there";"tX2s-Xas,2,XXunKnownData";
$ FIELD=2
$ echo '"Hello World";"Number 1 is there";"tH1s-Has,1,HHunKnownData";' | sed -r 's/(([^;]*;){'$((FIELD-1))'})([^;]*;)/\1\n\3\n/;h;s/[^\n]*\n([^\n]*).*/\1/;y/H1/X2/;G;s/([^\n]*)\n([^\n]*)\n([^\n]*)\n([^\n]*)/\2\1\4/'
"Hello World";"Number 2 is there";"tH1s-Has,1,HHunKnownData";
但可能有一种我没想到的简单方法。
答案 3 :(得分:0)
awk -F";" '{gsub("H","X",$3);gsub("1","2",$3);}1' Your_file
答案 4 :(得分:0)
这可能适合你(GNU sed):
sed 's/H/X/2g;s/1/2/2g' file
除了第一次出现H
或1
到X
或2
之外,其他所有内容都会发生变化
如果是按;
分隔的字段,请使用:
sed 's/H[^;]*;/&\n/;h;y/H/X/;H;g;s/\n.*\n//;s/1[^;]*;/&\n/;h;y/1/2/;H;g;s/\n.*\n//' file
这可以变异以适应许多值,所以:
echo -e "H=X\n1=2"|
sed -r 's|(.*)=(.*)|s/\1[^;]*;/\&\\n/;h;y/\1/\2/;H;g;s/\\n.*\\n//|' |
sed -f - file