1

Мне было поручено заменить целый ряд жестко закодированных идентификаторов в некотором коде (например: private static String MERCHANT_ID = "1234";) где-то ссылками на файл конфигурации (поэтому заменяемая версия для этого примера должна быть private static String MERCHANT_ID = ConstantMerchants.MERCHANT_A;).

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

Я уже составил список шаблонов регулярных выражений, которые соответствуют всем возможным обозначениям.

Есть ли способ использовать sed, чтобы заменить все старые строки на новые версии, если где-то есть файл конфигурации, содержащий старый шаблон, и чем он должен быть заменен?

Я ищу что-то, что позволяет мне определять шаблоны с новым значением, думать о чем-то похожем на это: (но затем с еще несколькими идентификаторами)

# old | new
/merchantId:\s*("|')1234("|'),/|merchantId: ConstantMerchants.MERCHANT_A
/private static String MERCHANT_ID\s*=\s*("|')1234("|');/|private static String MERCHANT_ID = ConstantMerchants.MERCHANT_A

Если бы я использовал какой-то другой инструмент, который поможет мне лучше решить эту проблему, я бы хотел услышать об этом. Я бы очень хотел использовать новую функцию Bash для Windows, но это только потому, что она выглядит круто :)

2 ответа2

2

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

/merchantId:\s*("|')[0-9]+("|')/b change
/private static String MERCHANT_ID\s*=\s*("|')[0-9]+("|')/b change
b
:change
s/["']1234["']/ConstantMerchants.MERCHANT_A/
s/["']1235["']/ConstantMerchants.MERCHANT_B/

Он начинается с каждого из ваших шаблонов, за которым следует команда b change которая означает переход к change метки при обнаружении шаблона. Список шаблонов заканчивается командой b которая означает переход до конца, т. Е. Перейти к чтению следующей строки ввода из файла.

Изменения :change означает, что это change метки, к которой мы переходим . Затем следует каждый ваш возможный номер, чтобы назвать переводы. Упрощение состоит в том, чтобы предположить, что в строке будет отображаться только одно число в кавычках, поэтому мы можем игнорировать, какой фактический образец соответствует. Если есть некоторые исключения, возможно, стоит обработать их вручную.

В системе Unix (я не знаю о Windows) вы можете использовать этот скрипт для редактирования файлов:

find dir -type f |
xargs sed -i -r -f sedscript

-i отредактирует файлы на месте, поэтому всегда начинайте с копирования файлов в новый каталог dir , затем запускайте эту команду для копии и используйте diff -ru между двумя каталогами, чтобы убедиться, что он делает то, что вам нужно , -r необходим (в Unix), чтобы GNU sed принимала (a|b) вместо обычного шаблона \(a\|b\) .

1

Посмотрев страницу MAN, вы увидите, что sed поддерживает параметр -f для предоставления файла сценария. Указанный файл должен содержать каждую замену для запуска, так как вы поставили бы ее непосредственно в sed . Например, у вас есть:

  • s/old/new/
  • s/new/old/

В отдельных строках файла он будет применять обе команды к тому, что вы предоставляете через stdout . Как пример: echo "old" | sed -f script.file с вышеуказанным содержимым приведет к выводу old.

Чтобы применить указанные правила к нескольким файлам, можно использовать цикл, в котором вы запускаете sed со сценарием для каждого файла и сохраняете изменения в самом файле. Другой вариант - использовать опцию -i и указывать "все" файлы в качестве аргументов командной строки. В зависимости от количества вы можете столкнуться с проблемами с общей длиной команды.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .