Как я могу найти и заменить первую фразу в нескольких файлах, содержащих фразу несколько раз?

3

Я хочу изменить первый фоновый цвет, следующий за

body {

стиль от всего, что он есть до

background-color: #000000;

в семи разных файлах stylesheets.css через командную строку. Также каждый файл .css содержит более 10 экземпляров, поэтому я хочу изменить только тот, который соответствует коду стиля body { .

    
задан Serge 16.12.2012 в 08:36
источник

3 ответа

2

Сделайте некоторые изменения в соответствии с вашим файлом:

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

или сделать это быстро:

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

Источник: Частые вопросы о часах

    
ответ дан yuan 16.12.2012 в 09:50
2

Как правило, вам нужно хорошее регулярное выражение, соответствующее вашим потребностям. sed - хороший инструмент для использования, perl - другой. Только причина, по которой я предпочитаю perl , заключается в том, что я лучше знаю ее синтаксис регулярных выражений. Следующая строка должна делать то, что вы хотите:

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

-0777 означает разделение на ничего, поэтому slurp в целом файле (вместо строки за строкой, по умолчанию для -p)

-i.bak означает изменение файлов на месте, оставляя оригинал с расширением .bak (по умолчанию для -p нужно просто распечатать)

-p означает, что строка за строкой (за исключением того, что мы разрываем) передаем код (см. -e)

-e ожидает выполнения кода.

Объяснение регулярного выражения выходит за рамки моего ответа, но есть много учебников, например этот например.

Обязательно проверьте результаты, поскольку я могу легко представить файлы css, которые могут вызвать проблемы с этим выражением. Например, наличие селекторов, содержащих тело слова, может вызвать проблемы ...

    
ответ дан Andy Friese 16.12.2012 в 10:41
1

Я бы попробовал awk :

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

Для этого требуется GNU awk (но может быть и без него).

  • Мы устанавливаем разделитель записей в } , за которым следует любое количество пробелов.
  • Затем мы можем сопоставить body { с началом записи.
  • И заменим background-color: #000000; на первый экземпляр background-color . Замените 1 g для соответствия всем экземплярам.
  • RT содержит текст, сопоставляемый разделителем записей. Если вместо регулярного выражения мы использовали фиксированную строку ( } ), вместо этого вместо нее можно было бы использовать ORS . RT требуется GNU awk.
  • GNU awk также имеет редактирование на месте плагин . Использовать gawk -i inplace ...

Воистину, это не работа для регулярных выражений или парсеров записей. Должно быть использовано то, что понимает язык CSS.

    
ответ дан muru 06.01.2015 в 08:06