4

Imagine I have an input file like this:

INSERT INTO video_item_theme VALUES('9', '29');
INSERT INTO video_item_theme VALUES('19', '312');
INSERT INTO video_item_theme VALUES('414', '1');

And I wish to add 10000 to only the first range of numbers, so I end up with something like this:

INSERT INTO video_item_theme VALUES('10009', '29');
INSERT INTO video_item_theme VALUES('10019', '312');
INSERT INTO video_item_theme VALUES('10414', '1');

My approach would be to prefix "1000" to one digit numbers, "100" Something like...:

sed 's/[0-9]\{2\}/10&/g' 

... isn't very helpful, since it changes each occurance of two numbers, not only in the first occurance of numbers:

INSERT INTO video_item_theme VALUES('9', '10029');
INSERT INTO video_item_theme VALUES('10019', '100312');
INSERT INTO video_item_theme VALUES('100414', '1');

3 Answers 3

3

Use awk instead of sed:

awk -F"'" '{OFS="'"'"'"; $2=$2+10000; print}'
1
  • 1
    +1 this might be a bit more readable: OFS="'\''" Sep 10, 2012 at 13:06
1

I don't know if there's an elegant way to do it with one command (and I don't think so), but you can easily do it with one command per length of numbers:

sed -e "s/'\([0-9]\{1\}\)',/\'1000\1\',/g"
sed -e "s/'\([0-9]\{2\}\)',/\'100\1\',/g"
sed -e "s/'\([0-9]\{3\}\)',/\'10\1\',/g"

The trick to change only the numbers you want is to include some context in the pattern, here the single quotes and the comma, so that your pattern is unique in your strings.

The result of each command is the following:

$ sed -e "s/'\([0-9]\{1\}\)',/\'1000\1\',/g" test
INSERT INTO video_item_theme VALUES('10009', '29');
INSERT INTO video_item_theme VALUES('19', '312');
INSERT INTO video_item_theme VALUES('414', '1');

$ sed -e "s/'\([0-9]\{2\}\)',/\'100\1\',/g" test
INSERT INTO video_item_theme VALUES('9', '29');
INSERT INTO video_item_theme VALUES('10019', '312');
INSERT INTO video_item_theme VALUES('414', '1');

$ sed -e "s/'\([0-9]\{3\}\)',/\'10\1\',/g" test
INSERT INTO video_item_theme VALUES('9', '29');
INSERT INTO video_item_theme VALUES('19', '312');
INSERT INTO video_item_theme VALUES('10414', '1');
3
  • Call me stupid, but that brings me: INSERT INTO video_item_theme VALUES('9', '10029'); INSERT INTO video_item_theme VALUES('10019', '100312'); INSERT INTO video_item_theme VALUES('100414', '1');
    – Marit Hoen
    Sep 10, 2012 at 11:29
  • maybe it was a syntax problem. I updated my answer and tested it, I have the results you wanted
    – m4573r
    Sep 10, 2012 at 11:37
  • Well feel free to validate the answer then ;)
    – m4573r
    Sep 10, 2012 at 11:48
0

Same solution as Ansgar Wiechers, but in perl:

perl -F\' -lane '$F[1] += 10000; print join "\047", @F' infile
  • -a auto-splits into @F at '.
  • -n loops over each line.

See perlrun(1).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .