0

我可以使用 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'... 让他们回来)第一个由 分隔的组;,这工作正常,但随后出现问题,如果我使用捕获,我需要选择整个组如果我不使用捕获,我会丢失数据。

4

5 回答 5

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";

不过,可能有一种我没有想到的更简单的方法。

于 2012-11-21T09:12:33.627 回答
1

[更新]

(我刚刚意识到它可以更短。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)单行。

于 2012-11-21T09:02:47.027 回答
1

如果 awk 适合您:

awk -F";" '{gsub("H","X",$3);gsub("1","2",$3);}1' OFS=";" file

使用 -F,文件以分号作为分隔符分割,因此现在第三个字段($3)是我们感兴趣的。gsub 函数在第 3 个字段中用 X 替换所有出现的 H,并再次替换为 1 到 2。

1是打印每一行。

于 2012-11-21T08:35:58.410 回答
0

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

sed 's/H/X/2g;s/1/2/2g' file

除了第一次出现Hor之外,这将分别更改1Xor2

如果是由;'s 分隔的字段,请使用:

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
于 2012-11-21T11:03:22.913 回答
0
awk -F";" '{gsub("H","X",$3);gsub("1","2",$3);}1' Your_file
于 2012-11-21T10:20:07.280 回答