从EXECUTE_COMMAND_LINE迭代复制文件

时间:2016-10-17 20:23:53

标签: bash io fortran csh

我有一个Fortran程序,每次调用程序(./test)时都会保存一个文件(fort.111)。

我创建了另一个程序(main.f90),它使用EXECUTE_COMMAND_LINE语句在每次启动第二个程序时将fort.111文件移动到另一个文件。

骨架应该是:

  1. 发布' ./ main'推出' ./ test' - >给我fort.111文件
  2. 我将fort.111移动到另一个文件#.dat
  3. 在主N次重复do循环。
  4. 这应该给我N file.dat,让我们说1.dat到N.dat。

    我的尝试是,对于test.f90程序:

    program test
    implicit none
    
    !! Create a file named fort.111 each time is launched
    open(unit=20,file='fort.111')
    
    write(20,*) 'I am the program called by main!'
    
    close(20)
    
    end program test
    

    对于主程序:

    program main
    implicit none
    
    integer :: i
    integer, parameter :: n = 1158
    
    call EXECUTE_COMMAND_LINE("COUNTER=0") ! initialize the counter
    do i = 1,n
       call EXECUTE_COMMAND_LINE("./test") ! launch the program ./test
       call EXECUTE_COMMAND_LINE("COUNTER=$((COUNTER + 1))") ! update the counter
       call EXECUTE_COMMAND_LINE("mv fort.111 $COUNTER.dat") ! mv the file to the new one
    end do
    
    end program main
    

    问题在于mv命令,因为我无法弄清楚如何将fort.111移动到1.dat并传递给下一个(即:fort.111 - > 2)。 dat,fort.111 - > 3.dat ...)

1 个答案:

答案 0 :(得分:1)

问题是你运行的每个EXECUTE_COMMAND_LINE都是在一个单独的shell中执行的。因此,当您调用$COUNTER命令时,mv基本上是空的。

  

9.93 EXECUTE_COMMAND_LINE - 执行shell命令

     

描述:      EXECUTE_COMMAND_LINE同步或以异步方式运行shell命令。

     

COMMAND参数传递给shell并使用C>库的系统调用执行。 (shell是在Unix系统上,而cmd.exe在> Windows上。)

糟糕的替代方案:

  • 尝试将COUNTER环境变量设置为i中的值,遗憾的是,Fortran似乎无法实现。也许来自C导入?我不是Fortran专家,5分钟前我甚至无法用正确的情况写出来:)
  • 为什么不直接使用mv从Fortran编写i命令行?那将是最干净的方式。但是,由于Fortran有限的字符串格式化,说起来容易做起来难。但是有一些例程可以为您处理,例如:http://www.gbenthien.net/strings/index.html
  • 最后一个选项:您可以生成一个临时bash字符串,其中包含临时目录中的所有命令,然后EXECUTE_COMMAND_LINE该字符串。

编辑:避免XY问题

为什么不在bash shell中创建一个简单的循环呢?下面的那个将做你需要的,不需要为此烦恼Fortran:

n=1158

COUNTER=0
while [ $COUNTER -lt $n ] ;
do
   ./test
   COUNTER=$((COUNTER+1))
   mv fort.111 $COUNTER.dat
done

或者roygvib提出的for循环在该上下文中更合乎逻辑,因为没有退出条件和计数器增加:

n=1158; for (( i = 1; i <= n ; i++ )) ; do ./test ; mv fort.111 $i.dat ; done