Как заменить строку в нескольких файлах в командной строке Linux

Мне нужно заменить строку в большом количестве файлов в папке, толькоssh доступ к серверу. Как я могу это сделать?

Ответы на вопрос(23)

ack '25 Essex' -l | xargs sed -i 's/The\ fox \jump/abc 321/g'

Также, если у вас есть пробел в результатах поиска. Вы должны избежать этого.

но с флагом g, чтобы заменить все вхождения в строке.

find ./ -type f -exec sed -i 's/string1/string2/g' {} \;

Для глобального нечувствительного к регистру:

find ./ -type f -exec sed -i 's/string1/string2/gI' {} \;
 07 мар. 2017 г., 21:27
Не делайте этого из корня проверенного репозитория Git. Вы можете случайно повредить его базу данных в.git/, Обязательноcd до более низкого уровня.
 18 июл. 2017 г., 22:25
Это действительно должен быть правильный ответ, но убедитесь, что у вас есть место после{} или вы получите ошибку.
 23 февр. 2017 г., 19:41
Подробный вариант был бы классным, но вы можете просто повторить, чтобы увидеть, были ли внесены изменения. Примечание. Для подстановочных знаков попробуйте "-name" *. Php ". и grep плохо с рекурсией и подстановочными знаками, вам нужно добавить--include=*.whatever с -r
 13 авг. 2015 г., 17:01
Если вы используете OSX, и ваши шаблоны могут содержать точки, и вы хотите заменить на месте (без файла резервной копии), вы должны использоватьLC_ALL=C find ./ -type f -exec sed -i '' -e 's/proc.priv/priv/g' {} \; (увидетьthis post а такжеthis one)
 17 февр. 2016 г., 12:30
Это определенно сработало для меня, поскольку позволяет фильтровать с -name & quot; *. Js & quot; & apos;

я написал служебный скрипт, который помогает рекурсивно заменить несколько пар старой / новой строки для всех файлов в каталоге.

Несколько пар старой / новой строки управляются в хэш-карте.

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

Требуется Bash 4.2, из-за некоторых новых функций.

en_standardize.sh:

#! /bin/bash
# (need bash 4.2+,)
# 
# Standardize phonetic symbol of English.
# 
# format:
#   en_standardize.sh [<dir>]
# 
# params:
# * dir
#   target dir, optional,
#   if not specified then use environment variable "$node_dir_en",
#   if both not provided, then will not execute,
# * 
# 

paramCount=$#

# figure target dir,
if [ $paramCount -ge 1 ]; then # dir specified
    echo -e "dir specified (in command):\n\t$1\n"
    targetDir=$1
elif [[ -v node_dir_en ]]; then # environable set,
    echo -e "dir specified (in environment vairable):\n\t$node_dir_en\n"
    targetDir=$node_dir_en
else # environable not set,
    echo "dir not specified, won't execute"
    exit
fi

# check whether dir exists,
if [ -d $targetDir ]; then
    cd $targetDir
else
    echo -e "invalid dir location:\n\t$targetDir\n"
    exit
fi

# initial map,
declare -A itemMap
itemMap=( ["ɪ"]="i" ["ː"]=":" ["ɜ"]="ə" ["ɒ"]="ɔ" ["ʊ"]="u" ["ɛ"]="e")

# print item maps,
echo 'maps:'
for key in "${!itemMap[@]}"; do
    echo -e "\t$key\t->\t${itemMap[$key]}"
done
echo -e '\n'

# do replace,
for key in "${!itemMap[@]}"; do
    grep -rli "$key" * | xargs [email protected] sed -i "s/$key/${itemMap[$key]}/g" @
done

echo -e "\nDone."
exit

replace "old_string" "new_string" -- file_name1 file_name2 file_name3

Если у вас есть все файлы, которые вы можете использовать

replace "old_string" "new_string" -- *

Если у вас есть список файлов с расширением, вы можете использовать

replace "old_string" "new_string" -- *.extension
 08 окт. 2014 г., 01:34
на самом деле & quot; - файл & quot; должно быть просто "-", по крайней мере, в моей версии
 14 окт. 2014 г., 18:00
Эта утилита распространяется в пакетах MySQL.
 20 мар. 2018 г., 17:54
Как вы включаете подкаталоги одного конкретного каталога?
 14 окт. 2014 г., 18:05
Хотя я хотел бы оценить решение, которое работает без кавычек регулярной строки, чтобы быть регулярным выражением.
 06 апр. 2016 г., 14:56
Это прекрасно работает - и если вы хотите заменить все строки в нескольких файлах, которые заканчиваются, например, на. & Quot; .txt & Quot; можно просто сделатьreplace "old_string" "new_string" -- *.txt

вы можете изменить разделитель на «+».

find . -type f -exec sed -i 's+http://example.com+https://example.com+g' {} +

Эта команда будет выполняться рекурсивно в текущем каталоге.

 08 мар. 2018 г., 18:29
Спасибо! Помогло изменить нагрузку на ссылки../domain.com вdomain.com

Это сработало для меня:

find ./ -type f -exec sed -i 's/string1/string2/' {} \;

Но это не так:sed -i 's/string1/string2/g' *, Возможно & quot; foo & quot; не должен был быть string1 и "bar" не строка2.

 17 мар. 2016 г., 01:19
Это потому, что sed трактует подстановочный знак * по-другому. [abc] * означает произвольное количество символов в наборе {a, b, c}. [a-z0-9] * работает аналогично шаблону *.
 16 апр. 2018 г., 13:03
На OSX используйте:find ./ -type f -exec sed -i '' -e 's/string1/string2/' {} \;

пользовать вторую строку для проверки.

grep -rl 'foo' . | xargs sed -i 's/foo/bar/g'
grep 'foo' -r * | awk -F: {'print $1'} | sort -n | uniq -c
 01 мая 2017 г., 23:07
Почему вы ссылаетесь на свой блог? Он содержит точно такой же текст, как и ваш ответ.
 11 июл. 2017 г., 23:04
мне нравитсяgrep -rl 'foo' . | xargs sed -i 's/foo/bar/g'

вы можете использоватьfind рекурсивно вывести список файлов, а затем выполнить операции сsed или жеperl.

Для наиболее быстрого использования вы можете найти командуrpl гораздо легче запомнить. Вот замена (foo -> gt), рекурсивно для всех файлов:

rpl -R foo bar .

Вам, вероятно, понадобится установить его (apt-get install rpl или похожие).

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

Support renaming of files as well as search-and-replace on file contents. See changes before you commit to performing the search and replace. Support regular expressions with back substitution, whole words, case insensitive, and case preserving (replace foo -> bar, Foo -> Bar, FOO -> BAR) modes. Works with multiple replacements, including swaps (foo -> bar and bar -> foo) or sets of non-unique replacements (foo -> bar, f -> x).

Чтобы использовать это,pip install repren. Проверьте README Например.

 01 нояб. 2017 г., 19:49
Вау, репрен отлично! Просто использовал его, чтобы изменить часть слова в именах классов, методах и переменных, переименовывая файлы, чтобы они соответствовали более чем 1000+ заголовочных и исходных файлов C ++, и с первого раза все работало идеально. Спасибо!

Чтобы заменить путь в файлах (избегая escape-символов), вы можете использовать следующую команду:

sed -i '[email protected][email protected][email protected]'

Знак @ означает, что все специальные символы должны игнорироваться в следующей строке.

 28 февр. 2018 г., 06:54
Именно то, что я искал во всех других ответах. А именно, как обращаться со специальными символами, например, при изменении строки, которая является путем. Спасибо. Похоже, большой упущение в других ответах.

script for multiedit command

Из ответа Каспара я создал скрипт bash, чтобы принимать аргументы командной строки и, необязательно, ограничивать имена файлов, соответствующие шаблону. Сохраните в вашем $ PATH и сделайте исполняемый файл, затем просто используйте команду выше.

Вот сценарий:

#!/bin/bash
_help="\n
Replace OLDSTRING with NEWSTRING recursively starting from current directory\n
\n

[-n PATTERN] option limits to filenames matching PATTERN\n
Note: backslash escape special characters\n
Note: enclose STRINGS with spaces in double quotes\n
Example to limit the edit to python files:\n
multiedit -n \*.py \"OLD STRING\" NEWSTRING\n"

# ensure correct number of arguments, otherwise display help...
if [ $# -lt 2 ] || [ $# -gt 4 ]; then echo -e $_help ; exit ; fi
if [ $1 == "-n" ]; then  # if -n option is given:
        # replace OLDSTRING with NEWSTRING recursively in files matching PATTERN
        find ./ -type f -name "$2" -exec sed -i "s/$3/$4/g" {} \;
else
        # replace OLDSTRING with NEWSTRING recursively in all files
        find ./ -type f -exec sed -i "s/$1/$2/" {} \;
fi

Ответ @ kev хороший, но он влияет только на файлы в ближайшем каталоге. В приведенном ниже примере используется grep для рекурсивного поиска файлов. Это работает для меня каждый раз.

grep -rli 'old-word' * | xargs [email protected] sed -i 's/old-word/new-word/g' @
 29 авг. 2016 г., 15:46
sed no input files, не работает
 25 окт. 2016 г., 07:22
вопрос специально для Linux, хотя.
 05 мар. 2014 г., 23:20
это не сработало для меня, но это сработало:grep --include={*.php,*.html,*.js} -rnl './' -e "old-word" | xargs [email protected] sed -i 's/old-word/new-word/g' @
 27 окт. 2017 г., 12:14
На OSX это нормально:grep -rli 'old-word' * | xargs [email protected] sed -i '' 's/2.0.0/latest/g' @
 09 нояб. 2015 г., 15:57
@pymarco Можете ли вы объяснить эту команду? Я не знаю, почему вы должны были использовать xargs вместо использования sed после|также почему-i в команде xargs? Я прочитал в руководстве это устарело и должен использовать-I вместо. И является@ используется в качестве разделителя для начала и конца для шаблона?

На MacBook Pro я использовал следующее (вдохновленныйhttps://stackoverflow.com/a/19457213/6169225):

sed -i '' -e 's/<STR_TO_REPLACE>/<REPLACEMENT_STR>/g' *

-i '' will ensure you are taking no backups.

-e for modern regex.

inplace & # x201D; когда вызывается с-i переключатель, который принимает файл резервной копии, заканчивающийся в качестве аргумента. Так

sed -i.bak 's/foo/bar/g' *

заменяетfoo сbar во всех файлах в этой папке, но не спускаются в подпапки. Это, однако, будет генерировать новый.bak файл для каждого файла в вашем каталоге. Чтобы сделать это рекурсивно для всех файлов в этом каталоге и всех его подкаталогах, вам нужен помощник, напримерfind, чтобы пройти по дереву каталогов.

find ./ -print0 | xargs -0 sed -i.bak 's/foo/bar/g' *

find позволяет вам дополнительные ограничения на какие файлы для модификации, указав дополнительные аргументы, такие какfind ./ -name '*.php' -or -name '*.html' -print0, если необходимо.

Примечание: GNUsed не требует окончания файла,sed -i 's/foo/bar/g' * тоже будет работать; FreeBSDsed требует расширения, но позволяет промежуток между ними, такsed -i .bak s/foo/bar/g * работает.

ы файлов

находить . | xargs grep строка поиска | sed & s; s / строка поиска / новая строка / g & apos;

например, найти. | xargs grep abc | sed 's / abc / xyz / g';

какой именно), и, хотя он не самый элегантный, он прост и, как начинающий пользователь Linux, не доставил мне никаких проблем.

for i in *old_str* ; do mv -v "$i" "${i/\old_str/new_str}" ; done

если у вас есть пробелы или другие специальные символы, используйте \

for i in *old_str\ * ; do mv -v "$i" "${i/\old_str\ /new_str}" ; done

для строк в подкаталогах используйте **

for i in *\*old_str\ * ; do mv -v "$i" "${i/\old_str\ /new_str}" ; done

очниках Python.

Вы можете попробовать подход grep / sed. Вот тот, который работает с GNU sed и не сломает git-репо:

$ grep -rli --exclude '*.git*' '#!/usr/bin/python' . | xargs -I {} \
gsed -i '' -e 's/#!\/usr\/bin\/python/#!\/usr\/bin\/env python/' {}

Или вы можете использоватьgreptile :)

$ greptile -x .py -l -i -g '#!/usr/bin/env python' -r '#!/usr/bin/python' .

Я только что проверил первый скрипт, и второй тоже должен работать. Будьте осторожны с escape-символами, я думаю, что в большинстве случаев проще использовать greptile. Конечно, вы можете делать много интересных вещей с помощью sed, и для этого предпочтительнее освоить его с помощью xargs.

To replace a string in multiple files you can use:

s/string1/string2/g'

Например.

grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'

Исходный блог

Если файл содержит обратную косую черту (обычно пути), вы можете попробовать что-то вроде этого:

sed -i -- 's,<path1>,<path2>,g' *

например:

sed -i -- 's,/foo/bar,/new/foo/bar,g' *.sh (in all shell scripts available)

Действительно хромая, но я не мог заставить любую из команд sed работать правильно на OSX, поэтому вместо этого я сделал эту глупую вещь:

:%s/foo/bar/g
:wn

^ - скопируйте эти три строки в мой буфер обмена (да, включите завершающий перевод строки), затем:

VI *

и удерживайте нажатой команду -v, пока не появится сообщение о том, что файлов не осталось.

Тупой ... Hacky ... эффективный ...

Решение Вопроса
cd /path/to/your/folder
sed -i 's/foo/bar/g' *

 18 июл. 2017 г., 22:31
Не работает рекурсивно.
 05 окт. 2014 г., 00:35
По крайней мере для моей версииsed, -i требует строки после нее, которая добавляется к старым именам файлов. Такsed -i .bak 's/foo/bar/g' *.xx двигает все.xx файлы к эквиваленту.xx.bak имя, а затем генерирует.xx файлы с подстановкой foo & # x2192; bar.
 21 дек. 2016 г., 09:44
@MatthewHerbst для выхода из пробелов, используйте \ likesed -i 's/foo\ with\ spaces/bar/g' *, Я полагаю, вы узнали об этом после стольких лет ... но так остаётся другим, которые находят ту же проблему.
 06 авг. 2014 г., 19:54
Мне кажется, это не работает, если в строке есть пробелы или специальные символы. Любая идея, почему это может быть, или мне нужно как-то избежать их? Спасибо!
 22 мая 2015 г., 11:40
Если кто-то хочет искать больше вариантов, есть ответ на обмен стека Unix, который охватывает больше вариантов использования сайтаunix.stackexchange.com/a/112024/13488
grep --include={*.php,*.html} -rnl './' -e "old" | xargs [email protected] sed -i 's/old/new/g' @

& quot; Вы также можете использовать find и sed, но я обнаружил, что эта небольшая строка perl прекрасно работает.

perl -pi -w -e 's/search/replace/g;' *.php
-e means execute the following line of code. -i means edit in-place -w write warnings -p loop

& Quot; (Извлеченный изhttp://www.liamdelahunty.com/tips/linux_search_and_replace_multiple_files.php)

Мои лучшие результаты получены от использования Perl и grep (чтобы убедиться, что файл имеет выражение поиска)

perl -pi -w -e 's/search/replace/g;' $( grep -rl 'search' )

From & quot; & Quot; К & Quot; - `find / path / to / folder -type f`

(replace - утилита замены строк MySQL Database System)

Ваш ответ на вопрос