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

awkで問題がない場合:

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

-Fを使用すると、ファイルは区切り文字としてセミコロンで分割されるため、3番目のフィールド($ 3)が重要になります。gsub関数は、3番目のフィールドでHのすべての出現箇所をXに置き換え、さらに1から2に置き換えます。

1はすべての行を印刷することです。

于 2012-11-21T08:35:58.410 に答える
1

[アップデート]

(私はそれがもっと短くなる可能性があることに気づきました。Perlには自動分割モードがあります):

$F[2] =~ s/H/X/g; $F[2] =~ s/1/2/g; $_=join(";",@F)

Perlは特に読みやすいことで知られていませんが、この場合、Perlで得られる最善の方法はsedPerlほど明確ではないかもしれません。

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-私はしばしばsedワンライナーのためにPerlに切り替えることに気づきます(私はまだ好きですが)。

于 2012-11-21T09:02:47.027 に答える
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 に答える
0
awk -F";" '{gsub("H","X",$3);gsub("1","2",$3);}1' Your_file
于 2012-11-21T10:20:07.280 に答える
0

これはあなたのために働くかもしれません(GNU sed):

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

Hこれにより、またはの最初の出現を除くすべてが、またはそれぞれ1に変更されますX2

;'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 に答える