一致する文字列のn番目の位置に文字を追加します。

一致する文字列のn番目の位置に文字を追加します。

長さ10の一致する文字列のn番目の位置に文字を挿入するsed / awkコマンドを見つける必要があります。たとえば、パターンで始まり、541長さ10の文字列を検索してから、置換なしで95番目の位置に文字列を挿入すると、11文字の文字列が生成されます。

文字列はスペースで区切られた単語です。また、パターンは常に単語の先頭にありますが、1行に複数の一致がある可能性があります。

入力ファイル:

5414444444 87654873234  88888888888
6646666666 54122222222 
54155555558888 54176543235 5416666666

結果ファイル:

54149444444 87654873234  88888888888
6646666666 54122222222 
54155555558888 54176543235 54169666666

答え1

OPは、aがそうでないwordことを意味することを例に見ることができます。string

sed 's/\b541./&9/g' file

Wordで他の場所から始めることが可能な場合541(最初からではありません)

sed 's/\b\S*541/\n&/g     #mark a beginning of word(s) with pattern
     s/\n\(....\)/\19/g   #remove mark and do adding
    ' file

次のように単語の記号数を制限できます。

sed 's/\b\(541.\)\(\S\{6\}\)\b/\19\2/g' file

またはより一般的に

sed 's/\b541./&\n/g;s/\n\S\{6\}\b/9&/g;s/\n//g' file

答え2

パールを使用できます

perl -lane 'map{length==10&&/^541/&&s/.{4}/$&9/}@F;print join(" ",@F)' file

マップを使用して、各フィールドに対して確認とサブタスクを実行します。次に、単一のスペースで連結されたフィールドの配列を印刷します(フィールド間の単一のスペースが一致しない場合、書式は混乱します)。

または単に正規表現を使用してください

perl -lane 'map{s/^541.\K.{6}$/9$&/}@F;print join(" ",@F)' file

出力:

54149444444 87654873234 88888888888
6646666666 54122222222
54155555558888 54176543235 54169666666

答え3

持ち運べる:

sed '
  s/.*/ & /; # add a leading and trailing space
  :1
    s/\([[:blank:]]541[^[:blank:]]\{2\}\)\([^[:blank:]]\{5\}[[:blank:]]\)/\19\2/g
    # replace in a loop until there is no more match
  t1
  # remove the blanks we added earlier:
  s/^ //;s/ $//'

末尾/先行スペースに加えて、リストの先頭または末尾に空白ではなく10個の文字列が表示されることを確認して、先行スペースと末尾スペースが一時的に追加されるのを防ぐことができます。これは正規表現を使用してPOSIX方式で実行できますが、少し不便です。

sed '
  :1
    s/^\(\(.*[[:blank:]]\)\{0,1\}541[^[:blank:]]\{2\}\)\([^[:blank:]]\{5\}\([[:blank:]].*\)\{0,1\}\)$/\19\3/
  t1'

そして、perl次のようにツアー演算子を使用します。

perl -lpe 's/((?<!\H)541\H\H)(\H{5})(?!\H)/${1}9$2/g'

または、単語を1つずつ処理します。

perl -lpe 's{\H+}{$&=~s/^541..\K.{5}$/9$&/r}ge'

\Kそしてr交換フラグには比較的新しいバージョンが必要ですperl)。

関連情報