#regex #perl #replace
#регулярное выражение #perl #заменить
Вопрос:
Мне нужно заменить немного текста в нескольких файлах css, но только в первом случае.
Я попытался заменить с:
perl -pi -e 's/(width:).*;/$1 100%;/' filename.css
Но это заменяет значение после каждого появления ‘width:’ в файле, даже если я не использую модификатор /g .
Я запускаю это на недавнем компьютере с Ubuntu.
Ответ №1:
Никто не обратился к подтексту вашего фактического вопроса о названии. Я рекомендую тот же подход, который использовался здесь, только измененный:
perl -pie '!$subbed{$ARGV} and s/(width:).*;/$1 100%;/ and $subbed{$ARGV} ' *.css
Безразмерное $ARGV
— это имя текущего файла. Таким образом, для каждого файла вы заменяете только первое вхождение. «Глобус» *.css
отправит несколько файлов. Если вы выполните скалярное переключение, которое предлагают другие пользователи, вы измените только первое вхождение в первом файле с помощью этого шаблона. (Хотя, возможно, это то, что вы хотите.)
Комментарии:
1. Хорошее решение. Я не знал, что это
$ARGV
содержит имя текущего файла.2. 1, передача нескольких файлов в однострочный формат очень полезна. Вы случайно не знаете способ получить больше файлов, чем
*.css
, например, все файлы вmyfolder
, повторно используя подкаталоги? Да, звучит похожеgrep
, но perl может сделать больше. 🙂 Например, вместо того, чтобы*.css
я пыталсяls *.css
, оно выдало мне предупреждение, но выполнило работу над содержимым файлов. Отсутствие одного ингредиента делает это без предупреждения.3. @zx81:
*.cc
Расширяется не perl, а операционной системой. Или, в случае Windows, вообще не используйте. Выполнение этого внутри однострочника, когда он просто ожидает обработки каждой строки, сложнее и больше связано с модулем. Вы могли бы поместить что-то в начальный блок для загрузки@ARGV
, но это становится более сложным.
Ответ №2:
Если вы читаете в режиме абзаца, каждый файл состоит всего из одной строки; следовательно, s /// без модификатора /g заменит первый экземпляр в каждом файле, а затем перейдет к следующему файлу:
perl -0777 -pi -e's/(width:).*;/$1 100%;/' *.css
Ответ №3:
Вы можете остановить замену после первого совпадения:
perl -pi -e '$a=1 if(!$a amp;amp; s/(width:).*;/$1 100%;/);' filename.css
Комментарии:
1. Или, короче:
... -e '!$x amp;amp; s/.../.../ amp;amp; ($x=1)'
. Также это работает, только если есть только один файл, как в вопросе. К сожалению, это не работает для нескольких файлов.2. @musikk, вот почему я внес свой ответ, который будет работать для нескольких файлов.
Ответ №4:
Вы можете попробовать это:
perl -pi -e 's/(width:).*;/$a?$amp;: $aamp;amp;"$1 100%;"/e' filename.css
Ответ №5:
Может s/(width:).*;/$1 100%;/o
сойдет?