Мне нужно заменить строку в большом количестве файлов в папке с ssh
доступом только к серверу. Как я могу это сделать?
461
cd /path/to/your/folder
sed -i 's/foo/bar/g' *
Появления «foo» будут заменены на «bar».
В системах BSD, таких как macOS, вам необходимо предоставить расширение для резервной копии, например -i '.bak'
или «риск повреждения или частичное содержимое» для man-страницы.
cd /path/to/your/folder
sed -i '.bak' 's/foo/bar/g' *
sed
,-i
требуется строка после нее, которая добавляется к старым именам файлов. Поэтомуsed -i .bak 's/foo/bar/g' *.xx
перемещает все.xx
файлы к эквивалентному.xx.bak
имени и затем генерирует.xx
файлы с подстановкой foo → bar.sed -i 's/foo\ with\ spaces/bar/g' *
. Я полагаю, вы узнали об этом так долго ... но так остаётся другим, которые находят ту же проблему.sed -i -e 's/foo/bar/g' $(find /home/user/base/dir)
Аналогично ответу Каспара, но с флагом g, чтобы заменить все вхождения в строке.
Для глобального нечувствительного к регистру:
источник
LC_ALL=C find ./ -type f -exec sed -i '' -e 's/proc.priv/priv/g' {} \;
(см. Этот пост и этот )--include=*.whatever
с -r.git/
. Обязательноcd
опускайтесь на более низкий уровень.git status
возвращается:error: bad index file sha1 signature.... fatal: index file corrupt
. Что дает?Ответ @ kev хорош, но влияет только на файлы в ближайшем каталоге. В приведенном ниже примере используется grep для рекурсивного поиска файлов. Это работает для меня каждый раз.
Распределение команд
Grep -r : --recursive , рекурсивно прочитать все файлы в каждом каталоге.
grep -l : --print-with-match , печатает имя каждого файла, у которого есть совпадение, вместо печати совпадающих строк.
grep -i : --ignore-case .
xargs : преобразовать STDIN в аргументы, следуйте этому ответу .
Команда xargs -i @ ~ содержит @ ~ : заполнитель для аргумента, который будет использоваться в определенной позиции в ~ команде ~ , знак @ - это заполнитель, который может быть заменен любой строкой.
sed -i : редактировать файлы на месте, без резервных копий.
СЭД с / регулярное выражение / замена / : заменой строки сопоставления регулярное выражение с заменой .
sed s / regexp / replace / g : global , делать замену для каждого совпадения вместо только первого совпадения.
источник
grep --include={*.php,*.html,*.js} -rnl './' -e "old-word" | xargs -i@ sed -i 's/old-word/new-word/g' @
|
, также, почему-i
в команде xargs? Я прочитал в руководстве это устарело и должен использовать-I
вместо этого. И@
используется как разделитель для начала и конца для шаблона?grep -rli 'old-word' * | xargs -I@ sed -i '' 's/2.0.0/latest/g' @
rli
) и@
знака, напримерЭто сработало для меня:
Но это не так
sed -i 's/string1/string2/g' *
. Может быть, «foo» не был строкой1, а «bar» - не строкой2.источник
find ./ -type f -exec sed -i '' -e 's/string1/string2/' {} \;
Есть несколько стандартных ответов на этот вопрос. Как правило, вы можете использовать find для рекурсивного вывода списка файлов, а затем выполнять операции с помощью sed или perl .
Для наиболее быстрого использования команда rpl гораздо проще запомнить. Вот замена (foo -> bar), рекурсивно для всех файлов:
rpl -R foo bar .
Вам, вероятно, понадобится установить его (
apt-get install rpl
или аналогичный).Однако для более сложных заданий, которые включают регулярные выражения и обратную подстановку или переименование файлов, а также поиск и замену, наиболее общий и мощный инструмент, о котором я знаю, это repren , небольшой скрипт на Python, который я написал некоторое время назад для некоторых более сложные задачи переименования и рефакторинга. Причины, по которым вы можете предпочесть это:
Чтобы использовать это
pip install repren
. Проверьте README для примеров.источник
Чтобы заменить строку в нескольких файлах, вы можете использовать:
Например
Исходный блог
источник
Чтобы заменить путь в файлах (избегая escape-символов), вы можете использовать следующую команду:
Знак @ означает, что все специальные символы должны игнорироваться в следующей строке.
источник
Если в вашей строке есть косая черта (/), вы можете изменить разделитель на «+».
Эта команда будет выполняться рекурсивно в текущем каталоге.
источник
../domain.com
наdomain.com
Первая строка вхождения «foo» будет заменена на «bar». И вы можете использовать вторую строку для проверки.
источник
grep -rl 'foo' . | xargs sed -i 's/foo/bar/g'
Если у вас есть список файлов, которые вы можете использовать
Если у вас есть все файлы, которые вы можете использовать
Если у вас есть список файлов с расширением, вы можете использовать
источник
replace "old_string" "new_string" -- *.txt
replace
утилиту. Без этой информации этот ответ неполон.«Вы также можете использовать find и sed, но я обнаружил, что эта маленькая строчка perl прекрасно работает.
"(Извлечено из http://www.liamdelahunty.com/tips/linux_search_and_replace_multiple_files.php )
Мои лучшие результаты получены от использования Perl и grep (чтобы убедиться, что файл имеет выражение поиска)
источник
Если вы хотите найти строку
search
и заменить ееreplace
в нескольких файлах, это моя проверенная в бою формула в одну строку :Быстрое объяснение grep:
-R
- рекурсивный поиск-i
- без учета регистра-I
пропустить двоичные файлы (вы хотите текст, верно?)-l
- распечатать простой список в качестве вывода. Необходим для других командЗатем вывод grep передается в sed (через xargs), который фактически используется для замены текста.
-i
Флаг будет изменять файл напрямую. Снимите его для своего рода «пробного запуска».источник
Я придумал собственное решение, прежде чем нашел этот вопрос (и ответы). Я искал различные комбинации «заменить», «несколько» и «xml», потому что это было мое приложение, но не нашел именно этого.
Моя проблема: у меня были весенние xml-файлы с данными для тестовых случаев, содержащие сложные объекты. Рефакторинг исходного кода java изменил много классов и не применим к файлам данных xml. Чтобы сохранить данные тестовых случаев, мне нужно было изменить все имена классов во всех XML-файлах, распределенных по нескольким каталогам. Все это при сохранении резервных копий оригинальных XML-файлов (хотя это не было обязательным, так как контроль версий спас бы меня здесь).
Я искал некоторую комбинацию
find
+sed
, потому что она работала для меня в других ситуациях, но не с несколькими заменами одновременно.Затем я нашел ответ на запрос ubuntu, и он помог мне построить мою командную строку:
И это сработало отлично (ну, в моем случае было шесть разных замен). Но учтите, что он затронет все файлы * .xml в текущем каталоге. Из-за этого, и если вы подотчетны системе контроля версий, вы можете сначала фильтровать и передавать только
sed
тем, у кого действительно есть нужные вам строки; подобно:источник
findstr /spin /c:"quéquieresbuscar" *.xml
это будет удобно.источник
Действительно хромая, но я не мог заставить любую из команд sed работать правильно на OSX, поэтому вместо этого я сделал эту глупую вещь:
^ - скопируйте эти три строки в мой буфер обмена (да, включите завершающий перевод строки), затем:
VI *
и удерживайте нажатой команду -v, пока не появится сообщение, что файлов больше не осталось.
Тупой ... Hacky ... эффективный ...
источник
На MacBook Pro я использовал следующее (вдохновлено https://stackoverflow.com/a/19457213/6169225 ):
источник
-e
просто говорит sed, что следующий токен - это команда. Для расширенных регулярных выражений используйте-E
вместо этого.Редактор потока изменяет несколько файлов «на месте» при вызове с
-i
коммутатором, который принимает в качестве аргумента файл резервной копии, заканчивающийся аргументом. Такзаменяет
foo
наbar
во всех файлах в этой папке, но не спускается в подпапки. Это, однако, сгенерирует новый.bak
файл для каждого файла в вашем каталоге. Чтобы сделать это рекурсивно для всех файлов в этом каталоге и всех его подкаталогах, вам нужен помощник, напримерfind
, для обхода дерева каталогов.find
позволяет вам дополнительно ограничивать, какие файлы изменять, указав дополнительные аргументы, напримерfind ./ -name '*.php' -or -name '*.html' -print0
, при необходимости.Примечание: GNU
sed
не требует окончания файла, такжеsed -i 's/foo/bar/g' *
будет работать; FreeBSDsed
требует расширения, но допускает пробел между ними, так чтоsed -i .bak s/foo/bar/g *
работает.источник
скрипт для мультиредактной команды
Из ответа Каспара я сделал скрипт bash, чтобы принимать аргументы командной строки и, необязательно, ограничивать имена файлов, соответствующие шаблону. Сохраните в вашем $ PATH и сделайте исполняемый файл, затем просто используйте команду выше.
Вот сценарий:
источник
Если файл содержит обратную косую черту (обычно пути), вы можете попробовать что-то вроде этого:
например:
источник
Чтобы сохранить свой личный английский узел, я написал служебный скрипт, который помогает рекурсивно заменить несколько пар старой / новой строки для всех файлов в каталоге.
Несколько пар старой / новой строки управляются в хэш-карте.
Dir может быть установлен через командную строку или переменную окружения, карта жестко запрограммирована в скрипте, но вы можете изменить код для загрузки из файла, если это необходимо.
Требуется Bash 4.2, из-за некоторых новых функций.
en_standardize.sh:
источник
Использование команды ack будет намного быстрее:
Также, если у вас есть пробел в результатах поиска. Вы должны избежать этого.
источник
Я привожу пример для исправления распространенной ошибки shebang в источниках Python.
Вы можете попробовать подход grep / sed. Вот тот, который работает с GNU sed и не сломает git-репо:
Или вы можете использовать greptile :)
Я только что проверил первый скрипт, и второй тоже должен работать. Будьте осторожны с escape-символами, я думаю, что в большинстве случаев проще использовать greptile. Конечно, вы можете делать много интересных вещей с помощью sed, и для этого предпочтительнее освоить его с помощью xargs.
источник
Я нашел это из другого поста (не помню, какой именно), и хотя он не самый элегантный, он прост и, как начинающий пользователь Linux, не доставил мне никаких проблем.
если у вас есть пробелы или другие специальные символы, используйте \
для строк в подкаталогах используйте **
источник
Команда ниже может быть использована для поиска файлов и замены файлов:
Например
источник
Существует более простой способ с использованием простого файла сценария:
откройте файл в gedit или редакторе по вашему выбору, я использую gedit здесь.
Затем в редакторе вставьте следующее в файл
Сохраните файл, закройте gedit , затем выйдите из терминала или просто закройте его и затем запустите, чтобы иметь возможность загрузить новый скрипт, который вы добавили.
Перейдите в каталог, где у вас есть несколько файлов, которые вы хотите редактировать. Затем запустите:
Нажмите ввод, и это автоматически заменит oldstring и oldstring1 во всех файлах, которые их содержат, на правильные newstring и newstring1 соответственно.
Он пропустит все каталоги и файлы, которые не содержат старых строк.
Это может помочь в устранении утомительной работы при наборе текста, если у вас есть несколько каталогов с файлами, которые требуют замены строки. Все, что вам нужно сделать, это перейти к каждому из этих каталогов, а затем выполнить:
#replace_string_files_present_dir
Все, что вам нужно сделать, это убедиться, что вы включили или добавили все строки замены, как я показал вам выше:
replace "oldstring" "newstring" -- *
в конце файла / bin / replace_string_files_present_dir .
Чтобы добавить новую строку замены, просто откройте созданный нами скрипт, набрав в терминале следующее:
sudo gedit /bin/replace_string_files_present_dir
Не беспокойтесь о количестве строк замены, которые вы добавляете, они не будут действовать, если старая строка не найдена.
источник
.gitlab-ci.yml
или atravis.yml
). Каждый поворот, заключающийся в написании сценария для его последующего выполнения, является анти-паттерном, поскольку вам нужно будет создать сценарий для создания сценария (а я в большинстве случаев$ replace "From" "To" - `find / path / to / folder -type f`
(replace - утилита замены строк MySQL Database System)
источник