В продолжение оригинальной проблемы, описанной здесь:- Копировать главы DVD в отдельные файлы
..кто-нибудь поможет нам понять, что делает следующий код:-
# count Titles, and count Cells per title.
# eg. ${cell[1]} is the Count of Cells for the first title
# ${cell[titles]} is the Count of Cells for the last title
eval $(lsdvd | sed -n 's/Title: \([0-9]\+\), .* Chapters: \([0-9]\+\), Cells: .*/cells[$((10#\1))]=$((10#\2));/p')
titles=${#cells[@]} title_num=2 from_cell=1 to_cell=${cell[title_num]}
Мы хотели бы сделать то же самое и попытались использовать код. К сожалению, он не работает у нас, и поскольку наше понимание ограничено, мы не можем его отладить.
Мы понимаем основную идею использования sed, но не можем понять, как ему удаётся:
- Разрешите любой шаблон для того, чтобы заменить.
- Создайте любой шаблон для замены.
Кроме того, его связь здесь с eval() находится за пределами нашего понимания. Плюс есть три использования #, которые мы просто не понимаем.
Помогите пожалуйста. Спасибо.
решение1
Во-первых, поскольку вы об этом не упомянули, я предполагаю, что это bash-скрипт.
Суть этих двух строк в том, что они извлекают номер заголовка и номер главы из выходных данных lsdvd
и сохраняют их в массиве с именем cells
.
Приведенный код, скорее всего, не работает, так как to_cell=${cell[title_num]}
в последней строке должно быть to_cell=${cells[title_num]}
.
Вот более подробный анализ:
Команда sed
ищет числа, следующие за Title:
и Chapters:
в выходных данных lsdvd
. sed
Затем сохраняет эти числа в \1
и \2
соответственно. sed
Выводит строку в форме cells[$((10#\1))]=$((10#\2))
, заменяя ссылки с обратной косой чертой на заголовок и номера глав.
Я полагаю, что вы тоже запутались в $((10#x))
синтаксисе. Вот разбивка: $((expression))
в bash означает «трактовать expression
как арифметическое выражение и вычислять его», в то время как y#x
является арифметическим выражением, означающим «трактовать x
как базовое y
число и преобразовывать его в десятичное». Так, например, 2#10
вычисляется как 2
(так как 10 представляет 2 в двоичной системе), 10#10
вычисляется как 10
(так как преобразование числа с основанием 10 в десятичное ничего не делает) и 3#4
выдает ошибку (так как «4» не является допустимым символом в тройной системе). Более подробную информацию можно найти в ARITHMETIC EVALUATION
разделе man bash
.
Итак, sed
команда просто выводит строку, которая выглядит так: cells[$((10#x))]=$((10#y))
где x
и y
— числа. Это передается в eval
. Я думаю, вы уже знаете достаточно, чтобы понять, что вычисление этой строки приводит к стандартному присваиванию массива в bash, поскольку после вычисления арифметических выражений строка выглядит как cells[x]=y
.
Последняя строка — это просто дополнительное назначение переменной с одним трюком. Она ${#cells[@]}
просто вычисляет количество элементов в cells
массиве.
Вот в чем суть.