[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

OpenVMS 用户手册


前页 目录 索引

9.2 排序文件

要排序文件,使用 DCL 命令 SORT。指定要排序文件名,用逗号分开,后面跟随排序后建立的输出文件的名称。

可选地,可以为想要排序的每个字段指定一个键。每个键包括以下信息:

  • 记录中键字段的开始位置 (必需的)
  • 键的大小 (必需的)
  • 键的数据类型
  • 记录排序的次序
  • 键的优先级

如果不指定任何键,Sort 假定只有一个键,并且这个键字段是:

  • 在记录的第一个位置开始
  • 包括整个记录
  • 包含字符数据
  • 按升序排序

以下两个例子使用默认键。

  1. 在这个例子中,文件 NAMES.LST 按升序排序:


    $ SORT NAMES.LST BYNAME.LST
    

    这个命令建立已排序的输出文件 BYNAME.LST,如图 9-1 所示。

    图 9-1 按升序排序的列表


  2. 在这个例子中,文件 NAMES.LST 和 NAMES2.LST 被排序到已排序的输出文件 BYNAME.LST。Sort 对待这些文件就象它们是一个大文件:


    $ SORT NAMES.LST,NAMES2.LST  BYNAME.LST
    

有关 SORT 限定词的完整列表,请参阅 9.9 节

9.2.1 定义键

使用 /KEY 限定词定义一个键。指定多个键时,为每个键使用一个独立的 /KEY 限定词。

表 9-2 描述组成键的 5 个元素。

表 9-2 /KEY 限定词值
键元素 描述
键位置 POSITION: n 键字段的第一个字节在记录中的位置。记录第一个字节的位置是 1。POSITION: n 是必需的。
键大小 SIZE: n 键字段的长度。SIZE: n 是必需的,浮点数据除外。

指定大小时,为键指定的数据类型确定什么值是可接受的。下表列出每类数据的可能值,和用来指定键大小的单位。

数据 有效范围 单位
字符 1 至 32,767 字符
二进制 1、2、4、8 或 16 (对于高性能 Sort/Merge 公用程序,二进制数据类型的键大小必须是 1、2、4 或 8 字节。对 16 字节二进制键的支持留待将来的 OpenVMS Alpha 发行版本。) 字节
十进制 1 至 31 数字
浮点 不需要值。

对于十进制数据,如果十进制符号存储在一个单独字节,那么这个字节不计入数据大小的计数中。

如果指定的键超出记录的末端,Sort 则把缺失的字符当作空字符。

数据类型 CHARACTER 字符数据。CHARACTER 是默认数据类型。
  BINARY 二进制数据。

SIGNED --- 有符号的二进制或十进制数据。SIGNED 是二进制和十进制数据的默认格式。

UNSIGNED --- 无符号的二进制或十进制数据。

  F_FLOATING F_FLOATING 格式数据。
  D_FLOATING D_FLOATING 格式数据。
  G_FLOATING G_FLOATING 格式数据。
  H_FLOATING 在 VAX 系统上,H_FLOATING 格式数据。(高性能 Sort/Merge 公用程序当前不支持。)
  S_FLOATING 在 Alpha 系统上,IEEE S_FLOATING 格式数据。
  T_FLOATING 在 Alpha 系统上,IEEE T_FLOATING 格式数据。
  DECIMAL 十进制数据。

TRAILING_SIGN --- 尾随符号的十进制数据。TRAILING_SIGN 是十进制数据的默认格式。

LEADING_SIGN --- 前导符号的十进制数据。前导符号必须在字段的第一个位置,而这个字段必须左侧无填补符。

OVERPUNCHED_SIGN --- 超额打孔的十进制数据。OVERPUNCHED_SIGN 是十进制数据的默认格式。

SEPARATE_SIGN --- 单独符号的十进制数据。

  ZONED 分区的十进制数据。(高性能 Sort/Merge 公用程序当前不支持。)
  PACKED_DECIMAL 压缩的十进制数据。
排序次序 ASCENDING 按递增的字母或数字次序进行排序操作。ASCENDING 是默认次序。
  DESCENDING 按递减的字母或数字次序进行排序操作。
键优先级 NUMBER: n 如果没有按照它们的优先级次序列出多个键,则通过它可指定每个键的优先级次序。可指定值从 1 至 255。

如果键字段的数据不是字符数据,必须指定其数据类型。Sort/Merge 公用程序识别以下数据类型:

BINARY,[SIGNED]  
BINARY,UNSIGNED  
CHARACTER  
DECIMAL,LEADING_SIGN,SEPARATE_SIGN [SIGNED]  
DECIMAL,LEADING_SIGN,[OVERPUNCHED_SIGN,SIGNED]  
DECIMAL [,SIGNED,TRAILING_SIGN,OVERPUNCHED_SIGN]  
DECIMAL,[TRAILING SIGN],SEPARATE_SIGN,[SIGNED]  
DECIMAL,UNSIGNED  
D_FLOATING  
F_FLOATING  
G_FLOATING  
H_FLOATING  
S_FLOATING,IEEE (只用于 Alpha 系统)  
T_FLOATING,IEEE (只用于 Alpha 系统)  
PACKED_DECIMAL  
ZONED  

在中括号内的项目是默认的,不需要指定。

注意

对于十进制字符串数据,Sort/Merge 公用程序为 VAX 和 Alpha 系统报告在输入串中有一个无效数字是不同的。在 VAX 系统上,您会接收到一条消息,告知为了比较把无效数字 (或保留操作数) 转换为有效的十进制字符串。在 Alpha 系统上,Sort/Merge 执行同样的转换,但不显示这条消息。在两种情况下,都把输入文件的数据不更改地写入输出文件。

图 9-2 中,文件 EMPLOYEE.LST 的每个记录包括 3 个字段: (1) 部门名、(2) 帐号和 (3) 雇员名。

图 9-2 列表中的记录字段


以下例子说明当使用或不使用一个键字段时,如何排序 EMPLOYEE.LST 中的记录:

  1. 在这个例子中,使用 /KEY 限定词描述帐号字段,按帐号排序 EMPLOYEE.LST:


    $ SORT/KEY=(POSITION:5,SIZE:4,DECIMAL)  EMPLOYEE.LST BILLING1.LST
    

    这个命令指定键字段 (帐号) 开始于位置 5,是 4 个字符长,包含十进制数据,并且应该按升序排序 (默认)。图 9-3 展示这个排序操作的结果。

    图 9-3 按键字段排序


  2. 这个例子展示没有指定键字段时,如何排序文件 EMPLOYEE.LST:


    $  SORT EMPLOYEE.LST BYDEPT.LST
    

    因为没有指定键,排序假定默认特征。图 9-4 展示这个排序操作的结果。

    图 9-4 用默认键记录排序



    Sort 把 EMPLOYEE.LST 的每个记录视为字符数据的一个键。在这个例子中,每个记录包括一个部门名、一个帐号和一个雇员名。如果 Sort 找到重复的部门名,它就按帐号排序部门名。如果它找到重复的复制帐号,它就按雇员名排序。注意,帐号是记录的一部分。除非另外指定,它被视为字符数据。

9.2.2 多键字段

排序可以使用一个以上的键 (多达 255 个键的极限)。可以按它们的优先级次序指定多个键:第一个是主键,下一个是辅助键,等等。另外,可以使用 NUMBER:n 指定键的优先级。每个键可以递增或递减。

在以下例子中,文件 EMPLOYEE.LST 排序首先按照雇员名键,然后 (当有同名记录时) 按照帐号键:


$  SORT /KEY=(POSITION:10,SIZE:15,CHARACTER) -
_$ /KEY=(POSITION:5,SIZE:4,DECIMAL) EMPLOYEE.LST BILLING2.LST

图 9-5 展示这个排序操作的结果。

图 9-5 用多键字段排序


在以下例子中,记录排序时首先按部门名的降序,然后按雇员名的升序:


$ SORT/KEY=(POSITION:1,SIZE:3,DESCENDING) -
_$ /KEY=(POSITION:10,SIZE:15) -
_$ EMPLOYEE.LST BILLING3.LST

图 9-6 展示这个排序操作的结果。

图 9-6 用多键字段排序 (升序和降序)


9.2.3 同样的键字段

按照默认,Sort/Merge 保留带同样键字段的记录,但是不维持它们在输入文件中出现的同样次序。要控制同键记录排序的方法,可指定以下限定词之一:

  • /STABLE
    维持同键记录的输入次序。当排序多个输入文件时如果使用这个限定词,那么输出同键记录时,第一个文件的同键记录在第二个文件的同键记录之前,以此类推。
  • /NODUPLICATES
    只保留同键记录的一个副本。如果想要指定保留哪个重复记录,那么在程序级调用 Sort 并指定一个等键例行程序。

/STABLE 和 /NODUPLICATES 限定词是不兼容的。在同一命令行中不能同时指定这两个限定词。

在以下例子中,从文件 EMPLOYEE.LST 中剔除重复帐号的记录:


$  SORT /KEY=(POSITION:5,SIZE:4)/NODUPLICATES EMPLOYEE.LST BUDGET.LST

图 9-7 展示这个排序操作的结果。

图 9-7 用同样的键字段排序


9.2.4 非字符数据

如果排序的记录包含非字符数据的项目,则指定每个键的数据类型。另外,小心地计算开始位置和大小,因为比较的项目可以占用 1 个以上字节。

如果要排序的文件记录包含 20 个字符后面跟随 3 个 F_floating 格式的浮点数,那么其位置如下所示:

  • 字符数据占用位置 1 至 20 (20 个字符)。
  • 第一个 F_floating 浮点数占用位置 21 至 24。
  • 第二个 F_floating 浮点数占用位置 25 至 28。
  • 第三个 F_floating 浮点数占用位置 29 至 32。

要按第三个浮点数排序文件,指定键字段如下:


$ SORT/KEY=(POSITION:29,F_FLOATING) STATS.RAW STATS.SOR

不需要指定浮点数的大小,因为它是固定四个字节。

9.2.5 输出文件组织

按照默认,排序产生一个输出文件,其文件组织与第一个输入文件相同。要指定不同的输出文件组织,可在 Sort 命令行中,在输出文件说明之后包括以下限定词之一:

  • /FORMAT (记录格式)
    当使用这个输出限定词时,可以定义文件记录格式、长度和块大小。
  • /INDEXED_SEQUENTIAL
    使用这个限定词,可以定义输出文件具有索引顺序文件组织。如果指定索引顺序作为输出文件组织,还必须完成以下步骤:
    • 在执行 Sort 操作之前,建立一个作为输出文件的空文件。Sort 需要一个已经存在的输出文件,并且是空的。
    • 在 SORT 命令行中,在输出文件名之后包括 /OVERLAY 限定词。/OVERLAY 限定词指出现有文件要被输入文件的排序记录覆盖。
  • /RELATIVE
    使用这个限定词,可以定义输出文件有相对文件组织
  • /SEQUENTIAL
    使用这个限定词,可以定义输出文件有顺序文件组织

在以下例子中,在索引顺序文件 EMPLOYEE.LST 排序之后产生一个顺序文件:


$ SORT/KEY=(POSITION:10,SIZE:15) -
_$ EMPLOYEE.LST BYNAME.LST/SEQUENTIAL

9.2.6 排序进程

Sort 安排文件时使用以下内部进程之一: 记录、标签、地址或索引。(高性能 Sort/Merge 公用程序只支持记录进程。对标签、地址和索引进程的实现留待将来的 OpenVMS Alpha 发行版本。) 指定的进程可以影响 Sort 操作的效率。有关优化 Sort 或 Merge 操作的详情,请参阅 9.8 节

下表描述四类进程。使用 /PROCESS=type 限定词可指定排序进程。

排序进程 类型 描述
记录 RECORD 排序时保持记录原样,并且产生一个包含完整记录的输出文件。记录是默认排序进程。
标签 TAG 只排序键字段,然后重新读取输入文件,产生一个包含完整记录的输出文件。其结果与一个完整记录排序一样。

如果磁盘空间很少,标签排序是有用的,因为在排序期间它通常使用较少的工作文件空间。在大多数情况下,标签排序比记录排序慢,因为它需要额外的时间重新读取输入文件。

地址 ADDRESS 只排序键字段,并且产生一个输出文件,这个文件是以二进制格式存储的记录文件地址 (RFA) 的索引。

地址排序比记录排序快,但是必须编写一个程序使记录地址与输入文件的记录关联。

索引 INDEX 只排序键字段,并且产生一个包含键和 RFA 的输出文件 (以二进制格式)。

与地址排序一样,索引排序比记录排序快,但是必须编写一个程序使记录地址与输入文件的记录关联。

9.3 指定比较顺序

字符根据比较顺序排序。对于包含字符数据的文件,可以使用 /COLLATING_SEQUENCE=sequence 限定词来指定比较顺序。下表描述比较顺序任选项:

比较顺序 顺序 描述
ASCII ASCII 字符数据的默认比较顺序。ASCII 顺序先是数字 (0 至 9),然后是大写字母 (A 至 Z),最后是小写字母 (a 至 z)。
EBCDIC EBCDIC 产生一个按 EBCDIC 顺序排序的输出文件。数据仍然是 ASCII 表示。EBCDIC 顺序先是小写字母 (a 至 z),然后大写字母 (A 至 Z),最后是数字 (0 至 9)。
DEC 多国字符集 MULTINATIONAL 多国比较顺序根据 DEC 多国字符集比较字符 (请参阅附录 A)。在MULTINATIONAL 字符顺序中,字符根据以下规则排序:
  • 所有读音格式的字符具有这个字符的比较值 (如,A'、A" 和 A` 比较为 A)。
  • 小写字母字符与它们的大写字母具有相同的比较值 (如,a 比较为 A,而 a" 比较为 A")。
  • 如果两个字符串比较为相同,就执行分解比较。继续比较字符串来检测由于区别音符、忽略的字符或虽然比较相同但实际上不同字符而导致的差别。如果字符串仍然比较为相同,那么就比较字符的数字代码。在最终比较后,小写字母字符排序在大写字母之前。
国家字符集 (NCS) 比较顺序名 命名的比较顺序必须定义在 NCS 库中。有关详情,请参阅 OpenVMS National Character Set Utility Manual

(高性能 Sort/Merge 公用程序不支持国家字符集 (NCS) 比较顺序。 对 NCS 比较顺序的支持留待将来的 OpenVMS Alpha 发行版本。)

用户自定义顺序 (顺序字符串) 指定一个用户自定义的比较顺序。用户自定义比较顺序只支持说明文件,而不支持命令行界面。

(高性能 Sort/Merge 公用程序不支持用户自定义的比较顺序。对用户自定义比较顺序的支持要留待将来的 OpenVMS Alpha 发行版本。)

    指定一个单字符、双字符或单字符范围的字符串,可定义一个比较顺序。(双字符是任何两个单字符的集合,比较时就象它们是一个字符。例如,"CH" 可以定义成比较为 "C"。) 这个字符串应该括入圆括号内。

也可以用其相应的八进制、十进制或十六进制值表示字符,但要使用基数运算符: %O、%D 和 %X。

当定义自己的比较顺序时,必须注意以下规则:

  • 把字符括入引号 ("") 内。
  • 用逗号 (,) 分开每个字符和字符范围,并把整个列表括入圆括号内。
  • 为出现在 Sort 或 Merge 操作的字符键的所有字符给出比较值。任何没有比较值的字符将被忽略,除非指定 FOLD 或 MODIFICATION 任选项。
  • 不要多次定义一个字符。
  • 不要使用引号 ("") 指定空字符。改为使用基数运算符,如 %X0。
  • 要指定引号,可把它们括入另一组引号 ("" "") 内,或者使用一个基数运算符。

以下字符串定义一个比较顺序,其中,双字符 LL 比较为一个在 L 和 M 之间的单字符。

("A"-"L","LL","M"-"Z")


注意

当使用多国比较顺序排序或合并文件以作进一步处理时,要谨慎使用。在大多数程序设计语言中的顺序检查过程比较数字字符。因为多国顺序基于实际的图形字符,而不是表示那些字符的代码,因此常规的顺序检查将失效。

以下例子示范使用说明文件建立用户自定义的比较顺序。有关说明文件的详情,请参阅 9.7 节

  1.  


    /COLLATING_SEQUENCE=(SEQUENCE=ASCII,IGNORE=("-"," "))
    

    这个 /COLLATING_SEQUENCE 限定词及指定的 IGNORE 任选项,导致以下字段在分解之前比较为相同:


           252-3412
           252 3412
           2523412
    
  2.  


    /COLLATING_SEQUENCE=(SEQUENCE=("A"-"L","LL","M"-"R","RR","S"-"Z"))
    

    这个 /COLLATING_SEQUENCE 限定词定义了一个顺序,在此顺序下,双字符 LL 比较为在 L 和 M 之间的一个单字符,而双字符 RR 比较为在 R 和 S 之间的一个单字符。另外,这些双字符也按通常的字母顺序出现。按照默认,这个用户自定义顺序不定义任何其他字符,如小写字母 a 至 z。


前页 后页 目录 索引