У вашей исходной команды sed
есть некоторые проблемы:
- Оператор чередования
|
не экранирован в первой группе и соответствует буквальному символу канала, поскольку шаблон анализируется какBRE POSIX regex - Первая группа разбита, поскольку конечный
)
не экранирован - Паттерн сопоставления цифр не используется, вы просто количественно
r
, r*
соответствует 0+r
буквы - В RHS нет заполнителя, и слово, захваченное в Группу 2, удалено (хотя вы испортили команду, экранируя последний
/
разделитель).
Вы можете исправить свою собственную команду, например
echo "/iil/path/data/file1" | \
sed 's/\(\/\|\)iil.*\(data\|log\|BinDir[0-9]\)/[PATH]\2/'
См. демо
Однако вы, скорее всего, захотите сопоставить с первым data
, log
и BinDir
, которые следуют сразу за /
.Таким образом, я предлагаю решение Perl, поскольку Perl поддерживает не жадные квантификаторы:
perl -pe 's,^/?iil/(?:.*?/)?(data|log|BinDir\d+),/$1,'
См. эту демонстрацию .
Подробности
^
- начало строки / строки /?
- необязательная /
iil/
- подстрока iil/
(?:.*?/)?
- необязательная группа без захвата, соответствующая 1 или 0 вхождениям любых 0+ символов, кроме символов разрыва строки, как можно меньше до первого вхождения последующих подшаблонов (data|log|BinDir\d+)
- группа1: data
, или log
или BinDir
, за которыми следуют 1+ цифр.
Замена: /$1
, косая черта и содержимое группы 1.