我希望从大型(~870,000,000行/ ~4GB)文本文件中提取某些行。作为一个小例子,在50行文件中,我可能需要3-6,18-27和39-45行。使用SO启动,并编写一些程序以我的数据为基准,似乎fortran90给了我最好的结果(与python,shell命令(bash)等相比......)。
我当前的方案只是打开文件并使用一系列循环将读指针移动到我需要的位置并将结果写入输出文件。
使用上面的小例子,这将是:
open(unit=1,fileName)
open(unit=2,outFile)
do i=1,2
read(1,*)
end do
do i=3,6
read(1,*) line
write(2,*) line
end do
do i=7,17
read(1,*)
end do
do i=18,27
read(1,*) line
write(2,*) line
end do
do i=28,38
read(1,*)
end do
do i=39,45
read(1,*) line
write(2,*) line
end do
*应该注意我在编译时假设缓冲的i / o,虽然这似乎只是最小化速度。
我很好奇这是否是完成任务的最有效方法。如果以上实际上是使用fortran90执行此操作的最佳方法,是否还有其他语言更适合此任务?
*更新:确保我使用缓冲的i / o,手动查找最有效的blocksize / blockcount。这增加了约7%的速度。我应该注意,我使用的文件没有固定的记录长度。
答案 0 :(得分:0)
您也可以尝试使用sed
实用程序。
sed '3,6!d' yourfile.txt
sed '18,27!d' yourfile.txt
Unix实用程序往往非常优化,并且可以非常快速地解决这样的简单任务。
答案 1 :(得分:-2)
一个人应该能够做到这一点是大多数语言,所以坚持这里的主题是一个应该接近工作,如果你解决错别字。 (如果我在iPad上有一个fortran编译器会使它更有用。)
PROGRAM AA
IMPLICIT NONE
INTEGER :: In_Unit, Out_Unit, I
LOGICAL, DIMENSION(1000) :: doIt
CHARACTER(LEN=20) :: FileName = 'in.txt'
CHARACTER(LEN=20) :: Outfile = 'out.txt'
CHARACTER(LEN=80) :: line
open(NEWunit=In_Unit, fileName) ! Status or action = read only??
open(NEWunit=Out_Unit, outFile) ! Status or action = new or readwrite??
DoIt = .FALSE.
DoIt(3:6) = .TRUE.
DoIt(18:27) = .TRUE.
DoIt(39:45) = .TRUE.
do i=1,1000
read(I_Unit,*) line
IF(doIt(I)) write(Out_Unit,*) line
end do
CLOSE(In_Unit)
CLOSE(Out_Unit)
END PROGRAM AA