Ubuntu: How can I find & replace first phrase, in multiple files containing the phrase multiple times?


I want to change the first background-color following the

body {  

style from whatever it is to

background-color: #000000;  

in seven different stylesheets.css files via command-line. Also each .css file contains more than 10 instances, which is why I want to only change the one following the body { style code.


Do some change according to your file:

sed  '0,/body{background-color:.*;/s//body{background-color:#000000;/' sample.css  

or do it quickly:

sed  '0,/body{background-color:.*;/s//body{background-color:#000000;/' *.css      

sed ':a;N;s/\n/\a/;$!ba;s/body[ \t\a]*{[ \t\a]*background-color:#[0-9a-zA-Z]*;/body\n{background-color:#000000;/;s/\a/\n/g;' *.css  

Source:The sed FAQ


Generally you need a good regular expression matching your needs. sed is a good tool to use, perl is another. Only reason I'm preferring perl is that I know its regular expression syntax better. The following line should do what you want:

perl -0777 -i.bak -pe 's/(body {.*?background-color.*?)#.{6}/$1#000000/si;' ./style.css  

-0777 means split on nothing, so slurp in whole file (instead of line by line, the default for -p)

-i.bak means alter files in place, leaving original with extension .bak (default for -p is to just print)

-p means pass line by line (except we are slurping) to passed code (see -e)

-e expects code to run.

Explaining the regular expression is beyond the scope of my answer, but there are many tutorials out there like this one for example.

Be sure to check the results as I can easily imagine css files which would cause problems with this expression. For example having selectors which contain the word body might cause problems...


I would try for awk:

gawk -v RS='}[[:space:]]*' '/^body[[:space:]]*{/ {     printf "%s%s", gensub (/background-color:[^;]*;/, "background-color: #000000;", 1), RT  }'  

This requires GNU awk (but can be done without it as well).

  • We set the record separator to } followed by any amount of whitespace.
  • Then we can match body { to the beginning of the record.
  • And substitute background-color: #000000; for the first instance of background-color. Replace 1 with g to match all instances.
  • RT contains the text matched by the record separator. If we used a fixed string (}) instead of a regular expression, we could use ORS instead. RT needs GNU awk.
  • GNU awk also has an in-place editing plugin. Use gawk -i inplace ...

Truly speaking, this is not a job for regular expressions or record parsers. Something that understands the CSS language should be used.

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »