首页 > 技术文章 > Fortran 循环进入文件夹,然后循环处理文件夹内的文件(批处理文件)

cfdchen 2020-07-22 09:11 原文

问题描述:代码计算的结果,按照时间顺序,分别存放在不同的文件夹内,但是结果文件具有相同的文件名字,如下:

/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

推荐阅读