Расширенная замена текста
Как я могу заменить текст во всех файлах во всех подпапках, если мой поиск включает "*", например, у меня много текстовых файлов, содержащих такой шаблон (некоторые неправильные пути, которые я хочу исправить)
/folder1/(abc)/params.launch
/folder2/(efd)/gui.launch
/folder3/(ghi)/robot.launch
Теперь я хочу добавить / запустить перед каждым файлом, чтобы иметь такой результат
/folder1/(abc)/launch/params.launch
/folder2/(efd)/launch/gui.launch
/folder3/(ghi)/launch/robot.launch
Я думал о поиске шаблона строки
")/*.launch"
но тогда как я могу заменить его, сохраняя содержание этих "*"
2 ответа
Должно быть довольно просто с sed:
sed 's;\([^/]*.launch$\);launch/\1;'
- Вы можете сгруппировать соответствующий текст, заключив выражение в скобки (
\( ... \)). Вы должны избежать скобок, чтобы сделатьsedвидеть их как специальный синтаксис. - Группы можно ссылаться с помощью позиции - первая группа
\1второе\2, так далее.
Пример вывода:
$ sed 's;\([^/]*.launch\);launch/\1;' foo
/folder1/(abc)/launch/params.launch
/folder2/(efd)/launch/gui.launch
/folder3/(ghi)/launch/robot.launch
Это для основных регулярных выражений. Для расширенных регулярных выражений можно использовать sed -r, в этом случае скобки не нужно избегать:
sed -r 's;([^/]*.launch);launch/\1;'
Наконец, в sedи некоторые другие инструменты, полный сопоставленный текст можно ссылаться с помощью &, избегая необходимости групп и обратных ссылок в целом:
sed 's;[^/]*.launch;launch/&;' foo
С помощью bash:
#!/bin/bash
while IFS= read -r line; do
ini="${line%/*}"
last="${line##*/}"
repl="${line##*.}"
echo "${ini}/${repl}/${last}"
done <file.txt
Выход:
/folder1/(abc)/launch/params.launch
/folder2/(efd)/launch/gui.launch
/folder3/(ghi)/launch/robot.launch
Здесь мы использовали замену параметра bash иметь три переменные:
iniпеременная будет содержать часть до последнего/например/folder1/(abc)lastпеременная будет содержать часть после последней/напримерparams.launchreplпеременная будет содержать то, что нужно поместить вiniа такжеlastпеременные т.е.launch
Затем мы напечатали значения переменных в указанном шаблоне, положив / между ними.