Конечно, нет необходимости писать какой-то большой длинный скрипт, когда требуется только подстановка, чтобы выполнить всю работу в одной строке. Вам просто нужно выбрать подходящий электроинструмент для работы.
Вот Perl с одним вкладышем:
% cat -n /tmp/f
1 import java.lang.Character;
2 import java.io.File;
3 import java.io.File;
4 import java.util.Pattern;
% perl -pe 's//IoException/ if m?import java\.io\.\KFile?' /tmp/f
import java.lang.Character;
import java.io.IoException;
import java.io.File;
import java.util.Pattern;
И если вы хотите сделать это с редактированием файла, просто добавьте -i.bak :
% perl -i.bak -pe 's//IoException/ if m?import java\.io\.\KFile?' /tmp/f
% head /tmp/f{,.bak}
==> /tmp/f <==
import java.lang.Character;
import java.io.IoException;
import java.io.File;
import java.util.Pattern;
==> /tmp/f.bak <==
import java.lang.Character;
import java.io.File;
import java.io.File;
import java.util.Pattern;
Причина, по которой это работает, заключается в том, что когда вы задаете для оператора m//
разделитель ??
, он имеет некоторое встроенное состояние, которое нужно запомнить, чтобы соответствовать только в первый раз.
Тогда в замене пустой шаблон означает повторное использование последнего сопоставленного шаблона, так что вам не придется вводить его снова и рисковать тем, что они когда-либо будут отклоняться.
Наконец, \K
в шаблоне отступает от матча, «удерживая» материал слева, чтобы он не сожрал заменитель.