2

背景:我们在这里使用磁带库和备份软件 NetWorker 来备份数据。安装的客户端是相当基本的,当我们需要恢复多个目标目录时,我们创建一个脚本,通过带有以下 X 行的脚本在后台简单地调用 X 个客户端实例:

recover -c client-srv -t "Mon Dec 10 08:00:00" -s barckup-srv -d /dest/dir/ -f -a /src/dir &

问题是同时从同一台机器备份的不同分区/目录可能分布在几个不同的磁带上,并且其中一些磁带可能已在备份和恢复之间从库中删除。

直到最近,这里的人们一直在找出需要哪些磁带的唯一方法是等待库抱怨它没有特定的磁带,或者在蹩脚的旧桌面 GUI 中设置虚假恢复客户端并点击特定的菜单选项。当磁带在异地并且需要一天时间才能取回时,第一种选择非常糟糕,而第二种选择既乏味又耗时。

实际问题:我编写了一个“元”脚本,它读取我们已经使用上述命令创建的脚本,将其输入交互式 CLI 客户端,并让它吐出所需的磁带,以及它们是否'实际上在图书馆。为此,脚本使用以下正则表达式提取必要的信息:

# pull out a list of the -a targets
restore_targets="`sed 's/^.* -a \([^ ]*\) .*$/\1/' $rec_script`"

# pull out a list of -c clients
restore_clients="`sed 's/^.* -c \([^ ]*\) .*$/\1/' $rec_script`"
numclients=`echo $restore_clients | uniq | wc -l`

# pull out a list of -t dates
restore_dates="`sed 's/^.* -t \"\([^\"]*\)\" .*$/\1/' $rec_script`"
numdates=`echo $restore_dates | uniq | wc -l`

我不太熟悉使用正s/\(x\)/\1/则表达式的类型,以至于我不记得名字了,但这是完成我正在做的事情的最佳方式吗?这些命令有效,但我想知道我是否在.*不必要地使用。

4

1 回答 1

1

\1指第一个捕获组。如果您替换foo(.*?)\1并输入foobar,则生成的文本变为bar\1指向第一个捕获组捕获的文本。

至于您的问题,使用 Python(或其他高级脚本语言)解析参数可能更安全、更容易:

>>> import shlex
>>> shlex.split('recover -c client-srv -t "Mon Dec 10 08:00:00" -s barckup-srv -d /dest/dir/ -f -a /src/dir &')
['recover', '-c', 'client-srv', '-t', 'Mon Dec 10 08:00:00', '-s', 'barckup-srv', '-d', '/dest/dir/', '-f', '-a', '/src/dir', '&']

现在,这更容易使用。引号消失了,命令的所有组件都很好地分成了一个列表。

如果您希望这完全是万无一失的,您可以argparse很容易地为此命令行使用和实现自己的解析器。这将使您能够轻松获取信息,但对于您的情况而言,这可能有点过头了。

至于您的实际问题,您可以剖析正则表达式:

^.* -t "([^\"]*)" .*$

此正则表达式捕获-t "foo \" bar",而非贪婪版本将停止在-t "foo \".

于 2012-12-20T17:22:28.837 回答