⎕NREAD¨t 82l∘,¨lׯ1+⎕?(⎕NSIZE t)÷l←10⍳⍨⎕NREAD 83 80,⍨t←⍞⎕NTIE 0
提示输入文件名,然后提示输入多少行。
说明
⍞提示输入文本(文件名)
⎕NTIE 0使用下一个可用的联系编号(在干净的系统上为-1 )
将文件联系在一起。
t←将所选的联系编号存储为t
83 80,⍨Append [83,80],产生[-1,83,80]
⎕NREAD读取前80个字节文件-1的8位整数(转换代码83)
10⍳⍨查找第一个数字的索引10(LF)
l←将行长
存储为l
(⎕NSIZE t)÷用文件长度的文件-1的大小除以行长
⎕提示输入数字(所需的行数) )
从前
?Y个自然数中减去X个随机选择(不替换),
¯1+加-1以获得0的行号*
l×乘以
t 82l∘,¨行长,以获取起始字节
将[-1,82,LineLength]前缀到每个起始字节(创建的参数列表⎕NREAD)
⎕NREAD¨ 将每行读为8位字符(转换代码82)
实际例子
文件/tmp/records.txt包含:
Hello
Think
12345
Klaus
Nilad
通过在APL会话中输入以下内容,使RandLines程序完全包含上述代码:
∇RandLines
⎕NREAD¨t 82l∘,¨lׯ1+⎕?(⎕NSIZE t)÷l←10⍳⍨⎕NREAD 83 80,⍨t←⍞⎕NTIE 0
∇
在APL会话中RandLines,按Enter。
系统将光标移动到下一行,这是字符数据的长度为0的提示符;输入/tmp/records.txt。
系统现在输出⎕:并等待数字输入。输入4。
系统输出四个随机行。
现实生活
实际上,您可能希望提供文件名并计数作为参数,并以表的形式接收结果。可以通过输入以下内容来完成:
RandLs←{↑⎕NREAD¨t 82l∘,¨lׯ1+⍺?(⎕NSIZE t)÷l←10⍳⍨⎕NREAD 83 80,⍨t←⍵⎕NTIE 0}
现在,使MyLines包含三个随机行,它们分别是:
MyLines←3 RandLs'/tmp/records.txt'
如果未指定count,如何只返回一条随机行:
RandL←{⍺←1 ⋄ ↑⎕NREAD¨t 82l∘,¨lׯ1+⍺?(⎕NSIZE t)÷l←10⍳⍨⎕NREAD 83 80,⍨t←⍵⎕NTIE 0}
现在,您可以同时执行以下操作:
MyLines←2 RandL'/tmp/records.txt'
和(注意没有左参数):
MyLine←RandL'/tmp/records.txt'
使代码可读
打高尔夫球的APL单衬板不是一个好主意。这是我在生产系统中的写法:
RandL←{ ⍝ Read X random lines from file Y without reading entire file
⍺←1 ⍝ default count
tie←⍵⎕NTIE 0 ⍝ tie file
length←10⍳⍨⎕NREAD 83 80,⍨tie ⍝ find first NL
size←⎕NSIZE tie ⍝ total file length
starts←lengthׯ1+⍺?size÷length ⍝ beginning of each line
↑⎕NREAD¨tie 82length∘,¨starts ⍝ read each line as character and convert list to table
}
*我可以通过在0来源模式下运行来保存字节,这在某些APL系统上是标准的:在之前¯1+插入和插入。1+10