按照此处描述的原始问题:- 翻录 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 中的 2),10#10
计算结果为10
(因为将基数 10 数字转换为十进制不会执行任何操作)并3#4
抛出错误(因为“4”不是基数 3 中的合法符号) 。更多信息可从ARITHMETIC EVALUATION
部分获得man bash
。
因此该sed
命令仅输出一个如下所示的字符串:cells[$((10#x))]=$((10#y))
其中x
和y
是数字。这被传递到eval
.我想你现在已经足够了解了,评估这个字符串只会导致 bash 中的标准数组赋值,因为在评估算术表达式之后,字符串看起来像cells[x]=y
.
最后一行只是一些额外的变量赋值,有一个技巧。${#cells[@]}
仅计算数组中的项目数cells
。
这就是它的要点。