Bash: Удаление фиксированного префикса и суффикса из строки
Узнайте, как удалить фиксированный префикс и суффикс из строк в Bash, используя расширение параметров. Пошаговый пример, лучшие практики и альтернативы.
Как удалить фиксированный префикс и суффикс из строки в Bash?
Например, имея:
string="hello-world"prefix="hell"suffix="ld"
Как извлечь среднюю часть строки, чтобы получить "o-wor"?
Чтобы удалить фиксированный префикс и суффикс из строки в Bash, можно использовать расширение параметров с двумя последовательными операциями: сначала удалить префикс с помощью ${string#pattern}, затем удалить суффикс из результата с помощью ${result%suffix}. Для вашего примера с string="hello-world", prefix="hell", и suffix="ld", вы выполните foo=${string#"$prefix"} затем foo=${foo%"$suffix"}, что вернет "o-wor".
Содержание
- Понимание основ расширения параметров
- Удаление префикса и суффикса двумя операциями
- Правила сопоставления шаблонов в Bash
- Практические примеры и варианты использования
- Распространённые ошибки и лучшие практики
- Альтернативные методы и инструменты
Понимание основ расширения параметров
Расширение параметров Bash — мощная функция, позволяющая манипулировать переменными и строками непосредственно в оболочке без создания внешних процессов. Согласно Stack Overflow, этот подход обычно является самым быстрым способом работы с переменными.
Ключевые операторы для удаления подстрок:
${var#pattern}– удаляет самый короткий совпадающий префикс${var##pattern}– удаляет самый длинный совпадающий префикс${var%pattern}– удаляет самый короткий совпадающий суффикс${var%%pattern}– удаляет самый длинный совпадающий суффикс
Как отмечено в статье Linux Journal, можно запомнить, какой оператор делает что, по их расположению на клавиатуре — # находится раньше %, так же как префиксы находятся раньше суффиксов в строке.
Важно: всегда заключайте шаблоны в двойные кавычки (
"${pattern}"), когда работаете с переменными, чтобы сохранить пробелы и предотвратить разбиение на слова.
Удаление префикса и суффикса двумя операциями
Чтобы удалить как префикс, так и суффикс из строки, необходимо выполнить два отдельных оператора расширения параметров, потому что, как объясняет один из ответов на Stack Overflow, «нельзя удалить и префикс, и суффикс в одном операторе».
Вот пошаговый процесс для вашего примера:
string="hello-world"
prefix="hell"
suffix="ld"
# Сначала удаляем префикс
foo=${string#"$prefix"} # Удаляет "hell" → оставляет "o-world"
# Затем удаляем суффикс из результата
foo=${foo%"$suffix"} # Удаляет "ld" → оставляет "o-wor"
echo "$foo" # Вывод: o-wor
Этот двухшаговый подход надёжно работает в большинстве случаев. Первый оператор ${string#"$prefix"} удаляет самый короткий совпадающий префикс в начале строки, а второй оператор ${foo%"$suffix"} удаляет самый короткий совпадающий суффикс в конце изменённой строки.
Правила сопоставления шаблонов в Bash
Bash использует правила сопоставления шаблонов, похожие на подстановку файлов при работе с globbing, при выполнении расширения параметров. Согласно Advanced Bash Scripting Guide, шаблоны разворачиваются и сопоставляются согласно определённым правилам.
Как работает сопоставление:
*соответствует любым символам (включая отсутствие символов)?соответствует любому одиночному символу[abc]соответствует любому символу из набора[!abc]соответствует любому символу, не входящему в набор
Например, если у вас:
string="prefix-mid-suffix"
prefix="pre*"
suffix="*fix"
Операции будут:
result=${string#"$prefix"} # Удаляет "pre*" → "mid-suffix"
result=${result%"$suffix"} # Удаляет "*fix" → "mid-suffix"
Как объясняет Stack Abuse, оператор %% удаляет самый длинный совпадающий шаблон с конца, а оператор # удаляет самый короткий совпадающий шаблон с начала.
Практические примеры и варианты использования
Обработка расширений файлов и путей
Один из распространённых вариантов — обработка путей файлов и расширений:
filename="document1-abc-123.txt"
extension=".txt"
prefix="document"
# Удаляем расширение
basename=${filename%"$extension"} # document1-abc-123
# Удаляем префикс
result=${basename#"$prefix"} # 1-abc-123
Обработка URL
url="https://www.example.com/page/path"
protocol="https://"
tld=".com"
# Удаляем протокол
domain=${url#"$protocol"} # www.example.com/page/path
# Удаляем TLD из домена
domain=${domain%"$tld"} # www.example.com/page
Реализация функции
Можно создать переиспользуемую функцию, как показано в Bash Commands:
remove_prefix_suffix() {
local string="$1"
local prefix="$2"
local suffix="$3"
# Удаляем префикс
local result="${string#"$prefix"}"
# Удаляем суффикс
result="${result%"$suffix"}"
echo "$result"
}
# Использование
string="hello-world"
prefix="hell"
suffix="ld"
result=$(remove_prefix_suffix "$string" "$prefix" "$suffix")
echo "$result" # Вывод: o-wor
Распространённые ошибки и лучшие практики
Кавычки вокруг шаблонов
Всегда используйте двойные кавычки вокруг шаблонов, чтобы корректно обрабатывать специальные символы и пробелы:
# Неправильно (провалится с пробелами или специальными символами)
foo=${string#$prefix}
# Правильно
foo=${string#"$prefix"}
Порядок операций
Порядок важен — всегда удаляйте префикс первым, затем суффикс:
# Неправильный подход
string="hello-world"
prefix="hell"
suffix="ld"
# Удаляем суффикс первым
wrong=${string%"$suffix"} # hello-wor
wrong=${wrong#"$prefix"} # o-wor (работает в этом случае, но ненадёжно)
# Правильный подход (всегда префикс сначала)
correct=${string#"$prefix"} # o-world
correct=${correct%"$suffix"} # o-wor (надёжно)
Обработка множественных совпадений
Если шаблоны могут встречаться несколько раз, используйте «жадные» версии:
string="abc123def123ghi"
prefix="abc"
suffix="ghi"
# Стандартные версии (удаляют самый короткий матч)
result=${string#"$prefix"} # 123def123ghi
result=${result%"$suffix"} # 123def123
# Жадные версии (удаляют самый длинный матч)
result=${string##"$prefix"} # 123def123ghi (то же, что выше)
result=${result%%"$suffix"} # 123def123 (то же, что выше)
Обработка ошибок
Рассмотрите возможность добавления обработки ошибок для случаев, когда шаблоны не совпадают:
remove_prefix_suffix() {
local string="$1"
local prefix="$2"
local suffix="$3"
# Проверяем наличие шаблонов перед удалением
if [[ "$string" == "$prefix"* ]]; then
string="${string#"$prefix"}"
fi
if [[ "$string" == *"$suffix" ]]; then
string="${string%"$suffix"}"
fi
echo "$string"
}
Альтернативные методы и инструменты
Использование sed
Хотя расширение параметров предпочтительнее, можно также использовать sed для более сложных шаблонов:
string="hello-world"
prefix="hell"
suffix="ld"
# Используем sed
result=$(echo "$string" | sed "s/^$prefix//" | sed "s/$suffix$//")
echo "$result" # Вывод: o-wor
Однако, как отмечает CopyProgramming, расширение параметров обычно быстрее, так как избегает создания внешних процессов.
Использование cut
Для простого удаления по количеству символов (не по шаблону) можно использовать cut:
string="hello-world"
prefix_length=4 # "hell" имеет 4 символа
suffix_length=2 # "ld" имеет 2 символа
# Вычисляем начальную и конечную позиции
start=$((prefix_length + 1))
total_length=${#string}
end=$((total_length - suffix_length))
# Извлекаем подстроку
result=${string:$start:$end}
echo "$result" # Вывод: o-wor
Использование ${string:offset:length}
Для извлечения подстроки по позициям (когда известны точные позиции):
string="hello-world"
# Извлекаем с позиции 4 (0‑based), длиной 5
result=${string:4:5} # o-wor
Как объясняет SQLPey, этот подход «избегает создания внешних процессов и обычно является самым быстрым способом работы с переменными».
Заключение
Удаление фиксированного префикса и суффикса из строки в Bash эффективно достигается с помощью расширения параметров двумя последовательными операциями. Самый надёжный метод — сначала удалить префикс с помощью ${string#"$prefix"}, а затем удалить суффикс из результата с помощью ${result%"$suffix"}. Этот подход позволяет извлечь «o-wor» из «hello-world», удалив «hell» и «ld».
Ключевые выводы:
- Всегда используйте двойные кавычки вокруг шаблонов, чтобы корректно обрабатывать специальные символы.
- Удаляйте префикс первым, затем суффикс для стабильных результатов.
- Расширение параметров быстрее, чем внешние инструменты вроде
sedилиcut, для простых операций. - Рассмотрите создание переиспользуемых функций для общих задач обработки строк.
- Обрабатывайте крайние случаи, когда шаблоны могут не совпадать или встречаться несколько раз.
Для более сложных задач обработки строк изучите полный набор возможностей расширения параметров Bash, описанный в Advanced Bash Scripting Guide и документации Bash.
Источники
- Stack Overflow – Remove a fixed prefix/suffix from a string in Bash
- Unix Stack Exchange – Pattern match both suffix and prefix in shell script
- Linux Journal – Bash Parameter Expansion
- Advanced Bash Scripting Guide – Parameter Substitution
- Stack Abuse – Guide to Parameter Expansion in Bash
- XModulo – How to manipulate strings in bash
- SQLPey – Shell Scripting: Multiple Methods to Extract Substring
- CopyProgramming – Bash: Eliminating a Constant Prefix/Suffix from a Bash String