使用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:lsdvdsed\1\2sedcells[$((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))其中xy是数字。这被传递到eval.我想你现在已经足够了解了,评估这个字符串只会导致 bash 中的标准数组赋值,因为在评估算术表达式之后,字符串看起来像cells[x]=y.

最后一行只是一些额外的变量赋值,有一个技巧。${#cells[@]}仅计算数组中的项目数cells

这就是它的要点。

相关内容