Удалить вариант из JAVA_OPTIONS с помощью сценария sh [duplicate]

Использование a вместо w должно позволить вам обновить файл вместо создания нового / перезаписать все в существующем файле.

См. этот ответ для разница в режимах.

254
задан Drise 14 June 2017 в 14:38
поделиться

22 ответа

cd /path/to/your/folder
sed -i 's/foo/bar/g' *

Возникновение «foo» будет заменено на «bar».

345
ответ дан Primož Kralj 15 August 2018 в 16:34
поделиться
  • 1
    Кажется, это не работает для меня, если в строке есть пробелы или специальные символы. Любая идея, почему это может быть, или мне нужно как-то избежать их? Благодаря! – Matthew Herbst 6 August 2014 в 18:54
  • 2
    По крайней мере, для моей версии sed, -i требуется строка после нее, которая добавляется к старым именам файлов. Таким образом, sed -i .bak 's/foo/bar/g' *.xx перемещает все .xx файлы в эквивалентное имя .xx.bak, а затем генерирует файлы .xx с заменой foo → bar. – Anaphory 4 October 2014 в 23:35
  • 3
    Если кто-то хочет найти больше опций, есть ответ на обмен файлами unix, который охватывает больше случаев использования сайта unix.stackexchange.com/a/112024/13488 – Reddy 22 May 2015 в 09:40
  • 4
    @MatthewHerbst, чтобы избежать пробелов, используйте \ like sed -i 's/foo\ with\ spaces/bar/g' *. Полагаю, вы так долго узнали ... но таким образом он остается для других, обнаруживающих ту же проблему. – manuelvigarcia 21 December 2016 в 09:44
  • 5
    Не работает рекурсивно. – FearlessFuture 18 July 2017 в 20:31

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

perl -pi -w -e 's/search/replace/g;' *.php
  • -e означает выполнение следующей строки кода.
  • -i означает редактирование на месте
  • -w записи предупреждений
  • -p loop

"(извлечено из 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' )
4
ответ дан Alejandro Salamanca Mazuelo 15 August 2018 в 16:34
поделиться

Команда «Ниже» может использоваться для первого поиска файлов и замены файлов

find. | строка поиска xargs grep | sed 's / search string / new string / g'

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

0
ответ дан Amit 15 August 2018 в 16:34
поделиться

Редактор потока модифицирует несколько файлов «inplace» при вызове с помощью переключателя -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, если это необходимо.


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

1
ответ дан Anaphory 15 August 2018 в 16:34
поделиться

$ заменить «От» «Кому» - `find / path / to / folder -type f`

(заменить - утилиту замены строк базы данных MySQL)

-4
ответ дан bashconsole 15 August 2018 в 16:34
поделиться

для команды multiedit

multiedit [-n PATTERN] OLDSTRING NEWSTRING

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

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

#!/bin/bash
_help="\n
Replace OLDSTRING with NEWSTRING recursively starting from current directory\n
multiedit [-n PATTERN] OLDSTRING NEWSTRING\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
2
ответ дан BBW Before Windows 15 August 2018 в 16:34
поделиться

Я придумал свое решение, прежде чем нашел этот вопрос (и ответы). Я искал разные комбинации «replace» «несколько» и «xml», потому что это было мое приложение, но не нашло его.

Моя проблема: у меня были весенние xml-файлы с данными для тестирования случаев, содержащих сложные объекты. Рефакторинг в исходном коде java изменил много классов и не применился к файлам данных xml. Чтобы сохранить данные тестовых случаев, мне нужно было изменить все имена классов во всех xml-файлах, распределенных по нескольким каталогам. Все, сохраняя резервные копии исходных xml-файлов (хотя это не было обязательным, так как управление версией меня спасло здесь).

Я искал некоторую комбинацию find + sed, потому что он работал для меня в других ситуациях, но не с несколькими заменами сразу.

Затем я нашел ask ubuntu response , и это помогло мне создать мою командную строку:

find -name "*.xml" -exec sed -s --in-place=.bak -e 's/firstWord/newFirstWord/g;s/secondWord/newSecondWord/g;s/thirdWord/newThirdWord/g' {} \;

И это сработало отлично (ну, у моего дела было шесть разных замен). Обратите внимание, что он будет касаться всех * .xml-файлов в текущем каталоге. Из-за этого, и если вы подотчетны системе управления версиями, вы можете сначала фильтровать и только перейти к sed тем, у кого есть нужные строки; например:

find -name "*.xml" -exec grep -e "firstWord" -e "secondWord" -e "thirdWord" {} \; -exec sed -s --in-place=.bak -e 's/firstWord/newFirstWord/g;s/secondWord/newSecondWord/g;s/thirdWord/newThirdWord/g' {} \;
4
ответ дан Community 15 August 2018 в 16:34
поделиться
  • 1
    и для окон я только узнал, что есть способ найти строку - не проверить еще, как ее заменить - в одной команде: findstr /spin /c:"quéquieresbuscar" *.xml Это будет удобно. – manuelvigarcia 8 June 2016 в 11:07
grep --include={*.php,*.html} -rnl './' -e "old" | xargs -i@ sed -i 's/old/new/g' @
3
ответ дан Dennis 15 August 2018 в 16:34
поделиться

Есть несколько стандартных ответов на это уже перечисленные. Как правило, вы можете использовать find для рекурсивного перечня файлов, а затем выполнять операции с sed или perl.

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

rpl -R foo bar .

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

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

  • Поддержка переименования файлов, а также поиск и замена содержимого файла.
  • См. Изменения перед выполнением поиска и заменить.
  • Поддерживать регулярные выражения с обратной подстановкой, целыми словами, нечувствительностью к регистру и сохранением регистров (замените foo -> bar, Foo -> Bar, FOO -> BAR).
  • Работает с несколькими заменами, в том числе свопами (foo -> bar и bar -> foo) или наборами неповторимых замен (foo -> bar, f -> x).

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

21
ответ дан Doctor Mohawk 15 August 2018 в 16:34
поделиться
  • 1
    Ничего себе, отлично! Просто использовал его для изменения части слова внутри имен, методов и переменных класса при переименовании файлов, чтобы они соответствовали заголовкам и исходным файлам с более чем 1000+ C ++, и он отлично работал в первый раз с одной командой. Спасибо! – Bob Kocisko 1 November 2017 в 19:49

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

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

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

Это требует 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 -i@ sed -i "s/$key/${itemMap[$key]}/g" @
done

echo -e "\nDone."
exit
1
ответ дан Eric Wang 15 August 2018 в 16:34
поделиться

Я приводил пример для исправления общей ошибки shebang в источниках python.

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

$ 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.

0
ответ дан exa 15 August 2018 в 16:34
поделиться

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

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

Однако этого не произошло: sed -i 's/string1/string2/g' *. Возможно, «foo» не предназначался для string1 и «bar» not string2.

23
ответ дан fedorqui 15 August 2018 в 16:34
поделиться
  • 1
    Это потому, что sed обрабатывает подстановочный знак * по-разному. [abc] * означает произвольное число символов множества {a, b, c}. [a-z0-9] * работает подобно шаблону *. – thepiercingarrow 17 March 2016 в 01:19
  • 2
    В OSX используйте: find ./ -type f -exec sed -i '' -e 's/string1/string2/' {} \; – Shaheen Ghiassy 16 April 2018 в 11:03

Если ваша строка имеет косую черту (/), вы можете изменить разделитель на «+».

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

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

6
ответ дан gopiariv 15 August 2018 в 16:34
поделиться
  • 1
    Благодаря! Помогло изменить нагрузку ссылок ../domain.com на domain.com – Jack Rogers 8 March 2018 в 18:29

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

sed -i 's@old_path@new_path@g'

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

13
ответ дан Ilya Suzdalnitski 15 August 2018 в 16:34
поделиться
  • 1
    Именно то, что я искал во всех других ответах. А именно, как обращаться со специальными символами, например, при изменении строки, которая является путем. Спасибо. Казалось, что большой надзор в других ответах. – inspirednz 28 February 2018 в 06:54

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

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

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

replace "old_string" "new_string" -- *

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

replace "old_string" "new_string" -- *.extension
8
ответ дан Jawahar Rakkiannan 15 August 2018 в 16:34
поделиться
  • 1
    фактически, & quot; - файл & quot; должен быть просто «-», по крайней мере, в моей версии – simpleuser 8 October 2014 в 00:34
  • 2
    – Dmitry Ginzburg 14 October 2014 в 17:00
  • 3
    Хотя я хотел бы оценить решение, которое работает без регулярного выражения регулярной строки. – Dmitry Ginzburg 14 October 2014 в 17:05
  • 4
    Это отлично работает - и если вы хотите заменить все строки в нескольких файлах, которые заканчиваются, например, & Quot; .txt & Quot; , вы можете просто сделать replace "old_string" "new_string" -- *.txt – tsveti_iko 6 April 2016 в 12:56
  • 5
    Как вы включаете подкаталоги одного конкретного каталога? – Pathros 20 March 2018 в 17:54

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

:%s/foo/bar/g
:wn

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

vi *

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

Dumb. ..hacky ... эффективный ...

2
ответ дан Justin 15 August 2018 в 16:34
поделиться

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

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

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

find ./ -type f -exec sed -i 's/string1/string2/gI' {} \;
150
ответ дан Kolob Canyon 15 August 2018 в 16:34
поделиться
  • 1
    Если вы находитесь на OSX, и ваши шаблоны могут содержать точки, и вы хотите заменить место (без файла резервной копии), вы должны использовать LC_ALL=C find ./ -type f -exec sed -i '' -e 's/proc.priv/priv/g' {} \; (см. этот пост и этот [ ) – Sheljohn 13 August 2015 в 15:01
  • 2
    Это определенно сработало для меня, поскольку оно позволяет фильтровать с -name & quot; *. Js & quot; – Marcello de Sales 17 February 2016 в 12:30
  • 3
    Вариант verbose будет крутым, но вы можете просто повторить grep, чтобы увидеть, были ли сделаны изменения. Примечание. Для подстановочных знаков попробуйте '-name & quot; *. Php & quot;' и grep плохо с рекурсией и подстановочными знаками, вам нужно добавить --include=*.whatever с -r – PJ Brunet 23 February 2017 в 19:41
  • 4
    Не делайте этого из корня проверенного Git repo. Вы можете случайно повредить свою базу данных в .git/. Убедитесь, что cd до нижнего уровня. – erikprice 7 March 2017 в 21:27
  • 5
    Это должен быть правильный ответ, но убедитесь, что у вас есть пробел после {} или вы получите сообщение об ошибке. – FearlessFuture 18 July 2017 в 20:25

Я нашел это из другого сообщения (не помню, какой), и хотя он не самый элегантный, он прост и, как новичок, пользователь 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
0
ответ дан Kyle Turck 15 August 2018 в 16:34
поделиться

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

grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @
96
ответ дан pymarco 15 August 2018 в 16:34
поделиться
  • 1
    это не сработало для меня, но это произошло: grep --include={*.php,*.html,*.js} -rnl './' -e "old-word" | xargs -i@ sed -i 's/old-word/new-word/g' @ – Dennis 6 March 2014 в 00:20
  • 2
    @pymarco Можете ли вы объяснить эту команду? Я не знаю, почему вам пришлось использовать xargs вместо использования sed после |, также, почему -i в команде xargs? Я прочитал в руководстве, это устарело, и вместо этого следует использовать -I. И @ используется как разделитель для начала и конца шаблона? – Edson Horacio Junior 9 November 2015 в 15:57
  • 3
    sed no input files, не работает – Vicky Dev 29 August 2016 в 13:46
  • 4
    не работает в osx – holms 25 October 2016 в 02:08
  • 5
    вопрос конкретно для Linux. – pymarco 25 October 2016 в 05:22

Чтобы заменить строку в нескольких файлах, вы можете использовать:

grep -rl matchstring somedir/ | xargs sed -i 's/string1/string2/g'

Например:

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

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

18
ответ дан remdezx 15 August 2018 в 16:34
поделиться

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

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

ex:

sed -i -- 's,/foo/bar,/new/foo/bar,g' *.sh (in all shell scripts available)
1
ответ дан Shaik Amanulla 15 August 2018 в 16:34
поделиться

Первая строка вхождения «foo» будет заменена на «bar». И вы можете использовать вторую строку для проверки.

grep -rl 'foo' . | xargs sed -i 's/foo/bar/g'
grep 'foo' -r * | awk -F: {'print $1'} | sort -n | uniq -c
9
ответ дан Sugato 15 August 2018 в 16:34
поделиться
  • 1
    Почему вы ссылаетесь на свой блог? Он содержит точно такой же текст, как и ваш ответ. – DavidPostill 1 May 2017 в 21:07
  • 2
    мне нравится grep -rl 'foo' . | xargs sed -i 's/foo/bar/g' – Prachi 11 July 2017 в 21:04
Другие вопросы по тегам:

Похожие вопросы: