11

Извлечение подстроки в Bash

11

Проблема: Извлечение пятицифрового числа из названия файла

У меня есть название файла в формате <code>someletters_12345_moreletters.ext</code>, и мне нужно извлечь пятизначную последовательность цифр и сохранить её в переменной.

Чтобы уточнить задачу: у меня есть название файла, состоящее из произвольного количества символов, затем располагается пятизначная последовательность цифр, окружённая одинарным знаком подчеркивания с обеих сторон, а затем идет еще одна произвольная последовательность символов. Мне необходимо извлечь это пятизначное число и сохранить его в переменной.

Я буду очень признателен за описание различных способов, с помощью которых это можно реализовать.

5 ответ(ов)

1

Попробуйте использовать команду cut -c startIndx-stopIndx. Эта команда позволяет извлекать определенные символы из строк, указывая диапазон индексов. Например, если вы хотите получить символы с 5 по 10, используйте cut -c 5-10. Убедитесь, что индексы начинаются с 1.

1

Ответ на ваш вопрос о том, как извлечь число из имени файла, может быть представлен несколькими способами, в зависимости от вашего конкретного случая. Вот несколько универсальных решений:

  1. Извлечение первого пятизначного числа из имени файла:
number=$(echo "$filename" | egrep -o '[[:digit:]]{5}' | head -n1)

Этот подход находит первую последовательность из пяти цифр.

  1. Извлечение части переменной по заданным смещениям и длине:
number="${filename:offset:length}"

Этот метод подходит, если вы знаете точное положение числа в строке.

  1. Если ваше имя файла всегда имеет формат stuff_digits_..., вы можете использовать awk:
number=$(echo "$filename" | awk -F _ '{ print $2 }')

Здесь мы разделяем строку по символу подчеркивания (_) и выводим второй элемент, который и будет вашим числом.

  1. Удаление всего, кроме цифр:
number=$(echo "$filename" | tr -cd '[[:digit:]]')

Этот способ убирает все символы, кроме цифр, из строки.

Выберите наиболее подходящий метод в зависимости от структуры ваших имен файлов!

0

Если кто-то хочет получить более детальную информацию, вы также можете поискать это в man bash, сделав следующее:

$ man bash [нажмите клавишу Enter]
/substring  [нажмите клавишу Enter]
[нажмите клавишу "n"]
[нажмите клавишу "n"]
[нажмите клавишу "n"]
[нажмите клавишу "n"]

Результат будет следующим:

${parameter:offset}
       ${parameter:offset:length}
              Расширение подстроки. Расширяется до максимум length символов
              параметра, начиная с символа, указанного offset. Если
              length опущен, расширяется до подстроки параметра, начинающейся
              с символа, указанного offset. length и offset являются
              арифметическими выражениями (см. НИЖЕ АРИФМЕТИЧЕСКОЕ
              ВЫЧИСЛЕНИЕ). Если offset оценивается как число меньше нуля, 
              значение используется как смещение от конца значения параметра. 
              Арифметические выражения, начинающиеся с -, должны 
              отделяться пробелом от предшествующего :, чтобы их не
              перепутали с расширением USE DEFAULT VALUES. Если length
              оценивается как число меньше нуля, и параметр не равен @ и не
              является индексированным или ассоциативным массивом, 
              он интерпретируется как смещение от конца значения параметра,
              а не как количество символов, и расширение — это символы между
              двумя смещениями. Если параметр равен @, результат — это 
              length позиционных параметров, начиная с offset. Если параметр 
              является названием индексированного массива с индексом @ или *, 
              результат — length элементов массива, начиная с 
              ${parameter[offset]}. Отрицательное смещение принимается относительно 
              одного, превышающего максимальный индекс указанного массива. 
              Применение расширения подстроки к ассоциативному массиву дает
              неопределенные результаты. Обратите внимание, что отрицательное 
              смещение должно быть отделено от двоеточия хотя бы одним пробелом, 
              чтобы избежать путаницы с расширением :- . Индексация подстрок 
              осуществляется с нуля, если используются позиционные параметры, 
              в противном случае индексация начинается с 1 по умолчанию. 
              Если offset равен 0 и используются позиционные параметры, 
              к списку добавляется $0.
0

Я удивлён, что не упомянули это решение на чистом Bash:

a="someletters_12345_moreletters.ext"
IFS="_"
set -- $a
echo $2
# выводит 12345

Вероятно, вы захотите восстановить значение IFS до его предыдущего состояния или выполнить unset IFS после использования!

0

В дополнение к ответу jor (который не работает для меня):

substring=$(expr "$filename" : '.*_\([^_]*\)_.*')

Этот код использует команду expr для извлечения подстроки из переменной filename. Он ищет часть строки между последним символом подчеркивания _ и следующим символом _. Однако, обратите внимание, что такой подход может не сработать в некоторых случаях, если имя файла не соответствует ожидаемому шаблону.

Если вам нужно более надежное решение, вы можете попробовать использовать команду sed или awk. Например, используя sed, вы можете сделать так:

substring=$(echo "$filename" | sed -E 's/.*_([^_]*)_.*/\1/')

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь