amin
amin

Reputation: 445

replace several matches of a substring with their indexes

assuming that you have a string with multiple occurrences of the same substring what would be the best one-liner to replace the matches with their another substring which contains the index of the math as well? As an example, let's say you have the following string: This is a test. and we want to replace all the occurrences of is with X and their index to have something like: ThX-0 X-1 a test.

Any ideas on this?

Upvotes: 0

Views: 48

Answers (3)

anubhava
anubhava

Reputation: 785246

Here is one alternative gnu-awk one liner:

echo 'This is a test.' | awk -v RS='[iI][sS]' '{ORS = "X-" i++} 1'

ThX-0 X-1 a test.

To reset counter for each line:

printf '%s\n%s\n' 'This is a test.' 'This is another this' |
awk -v RS='[iI][sS]' '/\n/{i=0} {ORS = "X-" i++} 1'

ThX-0 X-1 a test.
ThX-0 X-1 another thX-2

Upvotes: 0

RavinderSingh13
RavinderSingh13

Reputation: 133528

Simple solution in awk will be:

awk '{while(sub(/[iI][Ss]/,"X-"count++)){a=""};count=""} 1' Input_file

OR as per anubhava sir's comment adding above code's shorter version:

awk '{while(sub(/[iI][Ss]/,"X-"count++));count=""} 1'  Input_file

Simple explanation will be, run a loop till a substitution is found and do literally nothing inside it :) print the line at last.

Upvotes: 1

choroba
choroba

Reputation: 241908

Perl to the rescue!

echo 'This is a test.' | perl -pe 's/is/"X-" . $c++/ge' 
  • -p reads the input line by line, runs the code on it and outputs the processed line.
  • s///g runs a substitution globally, i.e. on all the positions where it's possible
  • /e interprets the replacement part as code and runs it. The code here uses the concatenation operator . on the string X- and the value of $c, increasing it by one at the same time.

Upvotes: 1

Related Questions