对话 UNIX: Squirrel--可移植的 shell 和脚本语言( 四 )


作为参考,清单 4 展示了一个 Ruby 脚本(作者为 Mr. Makshin),此脚本的功能与清单 3 相同 。即使该脚本已像 Ruby 那样简洁,但它在简洁性方面仍然逊色于 Squirrel Shell 代码 。
清单 4. 使用 Ruby 重新实现清单 3
 
!/usr/bin/ruby 
 
# List Directory contents. 
 
path = ARGV[0] == nil ? "." : ARGV[0].dup 
 
# Remove trailing slashes 
while path =~ //$/ 
 path.chop! 
end 
 
entrIEs = Dir.open(path) 
for entry in entries 
 unless entry == "." || entry == ".." 
filePath= "#{path}/#{entry}" 
fileStat = File.stat(filePath) 
if fileStat.directory? 
 puts "dir : #{filePath}" 
elsif fileStat.file? 
 puts "file: #{filePath}" 
end 
 end 
end 
 
entries.close()
有关 Squirrel 语言的更多信息,请参阅 Squirrel Programming Language Reference(参见 参考资料 获得链接) 。
巧妙的是,Squirrel Shell 中的几乎所有函数都去掉了底层操作系统的细节,因此您的代码可以尽可能保持通用 。例如,filename() 函数(在前两个清单中使用)将引导路径(leading path)从文件路径名中分离 — 比如,将 /home/example/some/Directory/file.txt 简化为 file.txt — 而不管您使用的是何种平台 。类似地,readdir() 和 filetype() 允许您不必了解真实的、底层操作和文件系统的圈套和陷阱 。通常,普通的 shell 并不能提供这种抽象(较为高级的脚本语言则可以) 。
其他有用的、独立于平台的功能包括 convpath() 和 run(),前者可以将路径名转换成本地路径名格式,而后者可以调用另一个可执行文件 。convpath() 函数可以执行双向转换,因此对于编写跨平台脚本非常有用 。
正则表达式
Shell 脚本通常用于自动化系统管理和维护工作 。实现这种自动化主要依靠正则表达式,它是用来查找、匹配和分解字符串的一组真正的象形文字 。如前所述,Squirrel Shell 需要 PCRE 库,这种库在 Perl、PHP、Ruby 和其他许多解释器和程序中都可找到 。PCRE 是用于数据处理的重要武器 。
尽管非常完整,Squirrel Shell 的正则表达式实现有一些不同,可能会令您想起 PHP 实现 。要在 Squirrel Shell 中使用正则表达式,需要先定义正则表达式,对其进行编译,进行比较,然后再迭代结果(如果有的话) 。
清单 5 展示的示例程序演示了 Squirrel Shell 中的正则表达式(代码由 Mr. Makshin 编写并且得到使用许可) 。
清单 5. 演示 Squirrel Shell 中的正则表达式
 
#!/usr/bin/env squirrelsh 
 
// Match a regular expression against text 
 
print("Text: "); 
local text = scan(); 
 
print("Pattern: "); 
local pattern = scan(); 
 
local re = regcompile(pattern); 
if (!re) 
{ 
 printl("Failed to compile regular expression - "regerror()); 
 exit(1); 
} 
 
local matches = regmatch(re, text); 
if (!matches) 
{ 
 printl("Failed to match regular expression - "regerror()); 
 regfree(re); 
 exit(1); 
} 
 
regfree(re); 
printl("Matches found:"); 
foreach (match in matches) 
 printl("t""substr(text, match[0], match[1])""");
在这里,scan() 从标准输出中读取一些文本和一个模式,但是并不包含通常用于确定正则表达式的起始和结束部分的前斜杠(/)字符 。
对于一个模式,函数 reqgcompile() 将编译此模式,这将提高匹配的速度 。您可以对 reqgcompile() 函数使用一个标记以启用或禁用区分大小写的功能(等同于 PCRE /i 修饰符),并且可以使用另一个选项针对一行或多行进行匹配(等同于 PCRE /m 选项) 。如果没有对正则表达式执行编译,那么所有匹配将失败 。

推荐阅读