Fortran 循环进入文件夹,然后循环处理文件夹内的文件(批处理文件)
问题描述:代码计算的结果,按照时间顺序,分别存放在不同的文件夹内,但是结果文件具有相同的文件名字,如下:
/postproc1/data.dat
/postproc2/data.dat
/postproc3/data.dat
...
现在要对大量结果文件进行后处理,将特定点上的数据导出,得到特定点上,压力随时间的变化关系。
我要用Fortran写个小程序来实现。代码如下:
1 program main 2 implicit none 3 4 character(len = 3) :: cTemp 5 character(len = 100) :: fileplace 6 integer, parameter :: time_sequence=27 ! number of time sequences = np 7 integer, parameter :: np=27 ! corresponding pressure = time_sequence 8 integer, parameter :: ntap=15 ! number of taps 9 integer :: tap(ntap) ! I index of taps (places) 10 integer :: k, i, j, m,n 11 real :: x,y,u,v,w,rho 12 real :: p(np,ntap) 13 14 data tap /603,643,666,685,700,715,727,740,751,762,773,799,826,857,895/ ! I index of the tap 15 16 17 do j = 1, ntap 18 19 write(*,"('Begin to figure out No.' i2 ' tap!')") j 20 21 do k = 584, 584+time_sequence-1 22 23 write(cTemp, '(i3)') k 24 fileplace = '/home/postproc'//trim(adjustl(cTemp))//"/" ! Name of the folder, not include the name of the target file 25 open(k,file=trim(adjustl(fileplace)) // "results_grid_1_tecplot.dat", form='formatted', status='old') 26 27 do i = 1, tap(j)+1 28 read(k,*) 29 end do 30 31 read(k,'(1x,7(1pe15.6))') x,y,u,v,w,rho,p(k-583,j) 32 close(k) 33 34 end do 35 36 end do 37 38 open(10,file='time_pressure_1-7.dat', status='new') 39 40 do m = 1, time_sequence 41 write(10,'(1x,I3,7(1pe15.6))') m, p(m,1), p(m,2), p(m,3), p(m,4), p(m,5), p(m,6), p(m,7) 42 end do 43 44 close(10) 45 46 open(20,file='time_pressure_8-15.dat', status='new') 47 48 do m = 1, time_sequence 49 write(20,'(1x,I3,8(1pe15.6))') m, p(m,8), p(m,9), p(m,10), p(m,11), p(m,12), p(m,13), p(m,14), p(m,15) 50 end do 51 52 close(20) 53 54 end
现在对代码说明如下:
14行,数组tap用于存放tap的I方向的索引值。
23行,将数字 k 赋值给字符串cTemp,用于记录文件夹名字中的数字。
24行,fileplace指定上文所说的不同的文件夹的名字,不包含要处理的文件的名字。因为文件夹的名字只有数字是不同的,所以要把数字给提取出来,作为字符串,这样的话,就可以循环进入不同的文件夹。其 中 // 是将字符串连接起来。adjustl将字符串的内容左对齐,空格置于右端,而trim的作用是把字符串后(就是右端)的空格去除。这三个命令都是Fortran内置的,可以直接使用。
末尾的"/"千万不能省略,因为这个斜杠将文件夹的名字与下文的文件的名字分隔开,如果没有这个斜杠,就不能正确地读到文件名。
25行, // 将文件夹的名字与文件的名字连接起来。
27行,do循环。因为read是按行的顺序来读的,而我要导出的数据不在第一行,因此,目标行之前的数据仍然要读,但是不做记录。
31行,将读取到的数据记录下来,其中数据最后一列是压力,将压力记录到数组p中,数组p的第一个索引代表时间序列,第二个索引代表哪一个tap(就是空间位置)。
'(1x,7(1pe15.6))' 表示输出的格式:
1x:表示将输出的位置向右移动一个位置;
7:表示将要记录的7个数据全都用这一个格式;
1pe15.6,其中p表示输出数据时的缩放值,其前的1表示1倍,即不缩放;e表示以指数类型输出浮点数,15.6表示使用15个字符字段,小数部分占7位。
40行,do循环,将数组p写出。这里,数据一共有15列,我分开来写了,输出到两个文件内。因为write这个命令,后边不能写太长,一共132位,超过这个值,编译的时候就会提示太长,需要分行写。分行写,用 & 这个符号写在行尾。
48行,同40行。
代码主要参考了以下两篇文章,感谢。
http://bbs.06climate.com/forum.php?mod=viewthread&tid=24905
https://stackoverflow.com/questions/16142292/defining-path-for-file-in-fortran