Seguindo o problema original descrito aqui: - Copie capítulos de um DVD para arquivos separados
..alguém poderia nos ajudar a entender o que o código a seguir está fazendo:-
# 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]}
Gostaríamos de fazer a mesma coisa e tentamos usar o código. Infelizmente isso não funciona para nós e como nosso entendimento é limitado, não podemos depurá-lo.
Compreendemos a ideia básica de usar o sed, mas não conseguimos entender como ele consegue: -
- Resolva qualquer padrão para substituir.
- Produza qualquer padrão para substituir.
Além disso, seu acoplamento aqui com eval() está além de nós. Além disso, existem três usos de # que também não entendemos.
Por favor ajude. Obrigado.
Responder1
Em primeiro lugar, como você não mencionou isso, presumo que seja um script bash.
O brilho de alto nível dessas duas linhas é que elas extraem o número do título e o número do capítulo da saída de lsdvd
e os armazenam em uma matriz chamada cells
.
O código fornecido provavelmente não funciona porque to_cell=${cell[title_num]}
na última linha deveria estar to_cell=${cells[title_num]}
.
Aqui está uma análise mais detalhada:
O sed
comando procura os números seguintes Title:
e Chapters:
na saída de lsdvd
. sed
em seguida, armazena esses números em \1
e \2
respectivamente. sed
gera uma string no formato cells[$((10#\1))]=$((10#\2))
, substituindo as referências de barra invertida pelo título e pelos números dos capítulos.
Acredito que você também esteja confuso com a $((10#x))
sintaxe. Aqui está o detalhamento: $((expression))
em bash significa "tratar expression
como uma expressão aritmética e avaliá-la", enquanto y#x
é uma expressão aritmética que significa "tratar x
como um número base y
e convertê-lo em decimal". Então, por exemplo, 2#10
avalia como 2
(já que 10 representa 2 na base 2), 10#10
avalia como 10
(já que converter um número de base 10 em decimal não faz nada) e 3#4
gera um erro (já que "4" não é um símbolo legal na base 3) . Mais informações estão disponíveis na ARITHMETIC EVALUATION
seção de man bash
.
Portanto, o sed
comando apenas gera uma string parecida com esta: cells[$((10#x))]=$((10#y))
onde x
e y
são números. Isso é passado para eval
. Acho que você já sabe o suficiente para perceber que avaliar essa string apenas resulta na atribuição de array padrão no bash, já que depois de avaliar as expressões aritméticas, a string se parece com cells[x]=y
.
A última linha é apenas uma atribuição adicional de variáveis, com um truque. ${#cells[@]}
apenas avalia o número de itens na cells
matriz.
Essa é a essência da questão.