Erwin Vrolijk
Erwin Vrolijk

Reputation: 363

Replace only first match in multiple files with perl

I need to replace a bit of text in multiple css files, but ony the first occurence.

I've tried replacing with:

perl -pi -e 's/(width:).*;/$1 100%;/' filename.css

But this replaces the value after every occurrence of 'width:' in the file, even though i'm not using the /g modifier. I'm running this on a recent Ubuntu machine.

Upvotes: 10

Views: 8264

Answers (5)

Altreus
Altreus

Reputation: 6229

If you read in paragraph mode, each file is only one line; hence the s/// without the /g modifier will replace the first instance in each file, then move to the next file:

perl -0777 -pi -e's/(width:).*;/$1 100%;/' *.css

Upvotes: 6

Axeman
Axeman

Reputation: 29854

Nobody has addressed an implication of your actual title question. I recommend the same approach as used here, only modified:

perl -pie '!$subbed{$ARGV} and s/(width:).*;/$1 100%;/ and $subbed{$ARGV}++' *.css

The un-dimensioned $ARGV is the name of the current file. So for each file, you're replacing only the first occurrence. The "glob" *.css will send multiple files. If you do the scalar switch that other people are suggesting, you will modify only the first occurrence in the first file with that pattern. (Though, perhaps that is what you want.)

Upvotes: 9

Roman Grazhdan
Roman Grazhdan

Reputation: 477

Maybe s/(width:).*;/$1 100%;/o would do?

Upvotes: 0

codaddict
codaddict

Reputation: 455122

You can stop the replacement after the first one:

perl -pi -e '$a=1 if(!$a && s/(width:).*;/$1 100%;/);' filename.css

Upvotes: 5

Qtax
Qtax

Reputation: 33908

You can try this:

perl -pi -e 's/(width:).*;/$a?$&:++$a&&"$1 100%;"/e' filename.css

Upvotes: 0

Related Questions