文字列インスタンスの範囲を変更する方法

文字列インスタンスの範囲を変更する方法

テキストファイルの各行にある部分文字列の一部のインスタンスを変更する必要があります。これらのインスタンスはすべて連続的です(例:3〜6または2〜5など)。このタスクにはどのようなコマンドが必要ですか?私が得た最も近いものは次のとおりです。

sed 's/this/that/3' file1

これは3回目だけ状況を変えます。同じことがあってほしい

sed 's/this/that/3,6' file1

答えかもしれませんが、sed範囲は表示されません。

入力例:

I want to change all letters "a" to "w" starting from the word "all" until the second "all" (inclusive)

予想出力:

I want to change wll letters "w" to "w" stwrting from the word "wll" until the second "all" (inclusive)

ベストアンサー1

そしてperl

3番目から6番目のasをsに変更しますb

$ echo aaaaaaaaa | perl -pe '$n=0; s{a}{++$n;$n==3..$n==6?"b":$&}ge'
aabbbbaaa

これは演算子eのフラグを使用するため、置換はs{regex}{replacement}flagsコードとして評価されます。これは、インクリメントされ"b"たカウンタが3から6の間で提供され、$&それ以外の場合は一致する値()が提供されます。または:

$ echo aaaaaaaa | perl -pe '$n=0; s/a(?(?{++$n; $n == 3 .. $n == 6})|(*FAIL))/b/g'
aabbbbaa

増加するカウンタが3〜6の範囲にない場合は、情報を(?(condition)yes|no)提供する正規表現演算子を使用してください。(*FAIL)

GNUは3番目それ以降のアイテムの交換をsedサポートしています。s/foo/bar/3gfoo

したがって、次の固定文字列の場合は、次のようにします。

$ echo aaaaaaaaa | sed 's/a/\n/3g;s/\n/a/5g;s/\n/b/g'
aabbbbaaa

つまり、最後の改行文字aから3番目の文字を改行文字に置き換え(パターンスペースで他の状況が発生しないように)、最後の改行文字から5番目の文字をs(6 - 3 + 1 = 4)に戻します。 。必要なas)の数aに応じて、次の項目を復元してから、残りのb改行をすべてsに置き換えます。

何でもsed:

sed 's/a/\
/g
s/\n/b/3
s/\n/b/3
s/\n/b/3
s/\n/b/3
s/\n/a/g'

最初の 2 つの発生の間の s をas に変更するには、次のようにします。wall

$ echo aaallaaallaaa | perl -pe 's{all.*?all}{$& =~ s/a/w/gr}e'
aawllwwwllaaa

\ball分離が必要な場合は、単語境界演算子を使用してください。性格

$ echo 'alloy (all-hands aaa ball all) fall' | perl -pe 's{all.*?all}{$& =~ s/a/w/gr}e'
wlloy (wll-hands aaa ball all) fall
$ echo 'alloy (all-hands aaa ball all) fall' | perl -pe 's{\ball\b.*?\ball\b}{$& =~ s/a/w/gr}e'
alloy (wll-hwnds www bwll wll) fall

-Mopen=localeASCIIのみと仮定するのではなく、ロケール文字マップに従ってデコードする文字を追加します。たとえば、alléeフランス語の単語をUTF-8にエンコードし、all後に単語以外の文字が続きません。)

おすすめ記事