Использование eval и sed для подсчета и управления скриптами

Использование eval и sed для подсчета и управления скриптами

В продолжение оригинальной проблемы, описанной здесь:- Копировать главы 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, но не можем понять, как ему удаётся:

  1. Разрешите любой шаблон для того, чтобы заменить.
  2. Создайте любой шаблон для замены.

Кроме того, его связь здесь с 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массиве.

Вот в чем суть.

Связанный контент