Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I need to edit lines in a file using sed. Now the problem is I am replacing a particular pattern with a combination of text and number. This number is a variable which keeps on incrementing for every subsequent line. Now as sed executes the command for all lines in one go, it is replacing the pattern found with the text and fixed number (i.e initial value of number).

For example:

k = 10
sed "s/raj/ram${k++}/"
share|improve this question
add comment

3 Answers 3

If your file is pretty small, this might work:

#!/bin/bash
for n in {1..40}
do
    sed -i $n's/raj/ram'$n'/' file
done 

It iterates over the file 40 times, and always replaces just 1 line. If you want to increment a counter not by line number, but by the number of lines you changed, you have to do it differently, with 2 variables, but the sed-command would be similar - n wouldn't be set by the loop.

sed -i changes the file in place, so if you want to keep the original, you have to make a copy first.

It can be done in a oneliner, if you prefer that:

for n in {1..40}; do sed -i $n's/raj/ram '$n'/' file ; done

Choosing the correct size instead of 40 automatically is possible too.

share|improve this answer
2  
You can use $(seq $(wc -l <input.txt)) instead of {1..40} for all lines of a specific file. –  ceving Aug 30 '11 at 11:04
    
Horribly inefficient on large files... –  Kusalananda Sep 9 '11 at 21:30
    
Yes, but no problem for small ones. Why I introduced it with if your file is pretty small, .... –  user unknown Sep 9 '11 at 21:59
add comment
awk -v n=10 '{sub(/raj/, "ram" n); print; n++}'
share|improve this answer
add comment

There are times to use sed, and there are times to not use it.
Because sed doesn't have built-in arithmetic, just use something else.
You can hack sed to do it (without a for-loop), but it is rather pointless and just a messy kludge compared to using something more suited.

With this input data:

printf '%s\n' 'a.raj' 'yyy' 'zzz' 'b.raj c.raj' >file
num=10 # start with this value

Here is a perl method, which increments each and every occurrence of raj (not just once per matched line)

perl -pe 'BEGIN{ $num='$((num-1))' }
          s/raj/ram.($num+=1)/ge' file

output:

a.ram10
yyy
zzz
b.ram11 c.ram12

Here is another perl version, which increments raj only once per matched line (ie. multiple matches on the same line have the same numeric suffix).

perl -pe 'BEGIN{ $num='$num' }
          if(/raj/){ s/raj/ram.$num/ge; $num+=1 }' file

output:

a.ram10  
yyy  
zzz  
b.ram11 c.ram11  

see: When should I NOT use sed

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.