许多 Linux 命令都包含允许您以有用方式排序数据的选项。例如,如果使用简单的 ls 命令,您可以指定 -t 选项按时间排序,或指定 -X 选项按扩展名排序。假设您希望只选择文件的所有者和名称,并按所有者排序结果,但 ls 没有包含允许此类输出的选项。如果您将数据集置于表中,可以执行以下操作:
SELECT file_owner, file_name FROM imaginary_table ORDER BY owner;但是,您可以使用管道操作符将命令的输出传送(或重定向)到其他命令,以获得所需结果。首先将数据限制为上面讨论的那两列:
| [root@linux-server test]# ls -l | awk '{print $3"\t"$9}' root xe_s000_2072.trc root xe_s000_2412.trc oracle xe_smon_2120.trc oracle xe_smon_3364.trc cas xe_smon_3664.trc cas xe_smon_3676.trc cas xe_smon_540.trc |
在本例中,使用了 awk 实用程序筛选数据,以便仅打印所有者和文件名。您可能已经注意到,所有者是虚构表的第三列,因此 $3 表示该列。\t 表示将使用一个标签将数据与下一列分隔开。但是,为什么要使用 $9?
仔细查看数据后发现,日期数据分为三列。由于使用了空格分隔这三部分,数据确实“看上去像是”三个单独的列。
现在,需要将这些结果传送到其他命令,以进行正确排序。排序实用程序将按字母顺序或指定的其他顺序打印各行。因此,您将获得以下所需结果:
[root@linux-server test]# ls -l | awk '{print $3"\t"$9}' | sort
cas xe_smon_3664.trc
cas xe_smon_3676.trc
cas xe_smon_540.trc
oracle xe_smon_2120.trc
oracle xe_smon_3364.trc
root xe_s000_2072.trc
root xe_s000_2412.trc
现在,假设您只想查看 oracle 所有的文件。SQL 语句将使用诸如 WHERE owner='oracle' 的 WHERE 子句。可以使用实用程序的 grep 选项限制数据,方法如下:
[root@linux-server test]# ls -l | awk '{print $3"\t"$9}' | sort | grep oracle
oracle xe_smon_2120.trc
oracle xe_smon_3364.trc
同样,可以使用 -v 标记将数据限制到非 oracle 所有(或等同于 WHERE owner <> 'oracle')的行:
[root@linux-server test]# ls -l | grep -v oracle
cas xe_smon_3664.trc
cas xe_smon_3676.trc
cas xe_smon_540.trc
root xe_s000_2072.trc
root xe_s000_2412.trc
特殊数据和分组数据
首先,假设只显示所有者数据(等效于 SELECT owner FROM imaginary_table ORDER BY 1):
[root@linux-server test]# ls -l | awk '{print $3}' | sort
cas
cas
cas
oracle
oracle
root
root
您可能希望查看目录中文件的所有者的简单列表。在 SQL 中,这将表达为:
SELECT DISTINCT owner FROM imaginary_table ORDER BY 1
您可以使用 uniq 命令获得类似结果:
[root@linux-server test]# ls -l | awk '{print $3}' | sort | uniq
cas
oracle
root
uniq 操作符具有一个 count 函数,允许您获得与给定所有者关联的每个文件的计数。在 SQL 中,您将编写以下查询:
SELECT count(*), owner FROM imaginary_table GROUP BY owner通过为 uniq 添加 -c 选项,您可以获得以下结果:
| [root@linux-server test]# ls -l | awk '{print $3}' | sort | uniq -c 1 3 cas 2 oracle 2 root |
输出开头处的 1 是什么?如果您回头查看 ls -l 命令的最初输出,可以看到有一行的内容是 total 60K。该输出再一次被命令解释为不包含任何数据的列 3。如果这不可接受,可以如前所示使用 grep 排除该行:
[root@linux-server test]# ls -l |grep -v total |awk '{print $3}' | sort | uniq -c
3 cas
2 oracle
2 root
上面的所有示例都使用 ls 命令提供输出。但是,产生输出的任何命令都可以通过类似的方式使用。另一个方法是,考虑是否可以将命令的输出重定向到一个文件。如果可以,得到的文件将包含随后可操作的数据集。
为了避免您认为熟悉这种类型的语法会占用您学习新事物和热门技术的时间,请考虑这些常用编码在 Ruby 编程语言中出现的方式。作为 Rails Web 应用程序开发框架的一部分,Ruby 获得了广泛的接受。无论如何,它是一种非常有用的通用语言,可用于解决系统管理员和 DBA 所关心的各种问题。
Oracle 和 SQL 有一个共同的特征,即,它们都是相对“密集”或“简洁”的语言。此类语言能够以简洁的方式表达极其强大的语句。这就使您能够创建更加简洁、更易于维护的程序。
以下示例可以在交互式 Ruby Shell (irb) 中执行,irb 包含在典型 Ruby 版本中。除了 Ruby 编程语言本身所需的前提条件以外,这些示例不需要任何其他安装条件。sort、uniq 和 grep 的以前用法反映在 ruby Array 类的方法名称中。
在命令行键入“irb”,转到 irb 提示符:
[root@linux-server test]# irb
irb(main):001:0>
创建数组对象中包含的值列表:
myList = ['ruby','sql','ruby','bash','python','perl','java','sql']
=> ["ruby", "sql", "ruby", "bash", "python", "perl", "java", "sql"]
在运行 irb 时,第二行将显示计算出的表达式的值。该值列表类似于前面示例中使用的 ls 命令的结果。该值列表将充当将要进行排序和限制的最初列表。
现在,可以对该列表进行排序:
irb(main):002:0> myList.sort
=> ["bash", "java", "perl", "python", "ruby", "ruby", "sql", "sql"]
可以返回一个特殊结果列表:
irb(main):003:0> myList.uniq
=> ["ruby", "sql", "bash", "python", "perl", "java"]
甚至还可以使用带有正则表达式匹配功能的 grep 方法:
irb(main):004:0> myList.grep(/r/)
=> ["ruby", "ruby", "perl"]
您还可以通过在 uniq 方法返回的数组上调用 size 方法,来模拟 uniq -c 选项:
irb(main):005:0> myList.uniq.size
=> 6

