Fortran Coder

查看: 20440|回复: 11
打印 上一主题 下一主题

[输入输出] 如何在Fortran中实现像shell里的sed命令那样的文件内容替换

[复制链接]

178

帖子

15

主题

0

精华

大宗师

F 币
4973 元
贡献
1152 点
跳转到指定楼层
楼主
发表于 2018-12-14 19:13:00 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式
简单点的,例如文件中的某行替换成某一个字符串
稍微难一点的,例如文件中的某些字符替换成某一个字符串
再复杂一点的,例如文件中符合条件的某些行进行特定替换操作或者类似于shell中awk那样的表控操作
其实吧,自行编写特定的Fortran子程序,对只有一行的文件都可以做到
但是Fortran似乎一旦只要写文件,就得从头到尾地写,没法实现Shell那样的中间替换
我曾试想过用Call System("")的语句,“”中是shell命令
这个问题是一次只能写一行,太复杂的shell命令实现不了
更大的问题是这样无法实现shell和Fortran的数据传递,这才是更要命的
各位大神,请问有什么办法没有……
分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

178

帖子

15

主题

0

精华

大宗师

F 币
4973 元
贡献
1152 点
12#
 楼主| 发表于 2018-12-15 16:33:43 | 只看该作者
fcode 发表于 2018-12-15 16:16
fortran程序执行多次

这样啊,那这样就是Fortran程序里只有一次循环的程序了
真正的循环结构在shell脚本里,这好像不是我想做的那个样子呢
不过如果把主程序写在shell脚本里,Fortran只有单次循环里的数据处理部分确实也可以哦
稍微麻烦一点大概就是Fortran程序每次被运行之后,之前的结果都“忘了”
如果嫌用文件I/O没效率的话,就需要每次来回给它和内存交互数据了
非常感谢版主的指点,我试试这种也尝试看能不能给自己编一些shell里那么好用的文字处理函数吧……

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

11#
发表于 2018-12-15 16:16:08 | 只看该作者
fortran程序执行多次

178

帖子

15

主题

0

精华

大宗师

F 币
4973 元
贡献
1152 点
10#
 楼主| 发表于 2018-12-15 14:32:53 | 只看该作者
fcode 发表于 2018-12-15 13:02
你可以通过Shell循环,然后把fortran 输出 write 的内容通过管道接收到,保存到内存里。
然后进行下一次循 ...

再想想,我知道了,你的意思是管道还可以继续往下接
不过怎么用循环来做迭代就想不出来了,要是版主能好心给个简单的例子就好了……

178

帖子

15

主题

0

精华

大宗师

F 币
4973 元
贡献
1152 点
9#
 楼主| 发表于 2018-12-15 13:07:52 | 只看该作者
fcode 发表于 2018-12-15 13:02
你可以通过Shell循环,然后把fortran 输出 write 的内容通过管道接收到,保存到内存里。
然后进行下一次循 ...

非常感谢
你是指Fortran写的执行程序只运行一次
但是在Shell脚本里在多个管道里使用它,直到完成任务为止?

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

8#
发表于 2018-12-15 13:02:36 | 只看该作者
你可以通过Shell循环,然后把fortran 输出 write 的内容通过管道接收到,保存到内存里。
然后进行下一次循环。

这是没有问题的,我们也经常利用这种方法来做迭代。

178

帖子

15

主题

0

精华

大宗师

F 币
4973 元
贡献
1152 点
7#
 楼主| 发表于 2018-12-15 12:48:28 | 只看该作者
fcode 发表于 2018-12-15 11:30
管道当然可以呀

哈,谢谢版主,好有趣的功能,非常有启发性
这确实是把通过shell管道得到数据作为Fortran程序的输入了唉
不过还是和我预想的功能有些不太一样,应该还是我描述的不完整
实际上我的程序可能会有shell何Fortran程序来回互传数据啊
唉,还不如完整说下我的问题吧
我其实是想用Fortran写一个vasp用的脚本
实现的功能是多次调用vasp进行计算,根据每次计算得到的能量调整输入的POSCAR文件
在这里,每次从vasp的结果文件中读入能量和改写POSCAR文件都是用Shell文字处理比较方便的
但是对于根据得到的能量进行优化计算,这些都是用Fortran更合适
所以需要做的流程实际上是:
调用vasp(shell)->读入vasp输出文件中的能量(shell)->计算得到优化结构(Fortran)->改写vasp输入文件POSCAR(shell)->调用vasp(shell)
这样的循环,所以需要来回在shell和Fortran中互传数据
我试想了一下,版主这种方式似乎只有在读入能量给Fortran中这一步是好用的
如果互传数据只有这一步应该是可以用的,可惜不仅仅是啊

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

6#
发表于 2018-12-15 11:30:11 | 只看该作者
管道当然可以呀

QQ截图20181215112933.png (119.73 KB, 下载次数: 437)

QQ截图20181215112933.png

178

帖子

15

主题

0

精华

大宗师

F 币
4973 元
贡献
1152 点
5#
 楼主| 发表于 2018-12-15 11:10:40 | 只看该作者
vvt 发表于 2018-12-15 10:33
说真的,Fortran的文本处理能力的确不怎么样。
你用Shell处理大文件也一样的消耗内存的。并没有什么本质区 ...

一样耗内存啊,我还以为shell的脚本有什么优化方法能减少内存消耗呢
既然如此,用Fortran给自己写一些类似于sed,awk,head,tail之类的封装至成熟也是可行啊
不过这个有点耗时间,对于一些小问题可能还是想用shell和Fortran混合编程了

至于对于数据互传,看来我的表述方式有问题,让大佬你误解了
我倒不是说能有什么大量数据的互传
就是说有没有什么办法在用Shell和Fortran混合编写的时候,
在内存里两种程序语言间互传数据,目前我是先把数据写到文件里再用另外一种语言去读
这样的文件I/O据说速度很低,应该尽量避免啊,希望能有类似于shell里的管道的方式

举个例子,比如某个文件里我希望读取最后一行第二个空格后的数据
然后接下来这个数据要用于Fortran计算
从文字处理上,直接用shell里的awk命令显然是最省心的
可是问题是用shell读出来了,Fortran程序里却是没有这个数据的,哪怕作为字符串也没有
那么有没有不用文件I/O的方法把这个数据或者字符串传递给Fortran程序呢
当然,大佬你之前说的很对,这个功能可以自己写一个Fortran子程序在Fortran内部实现
但是如果大量涉及到类似的东西的话,就除非自己写一个函数库了
所以我就像问下,如果采用shell和Fortran混合编程结合优势的话有没有什么好办法实现这种数据互传

另外,我不太了解C,是不是C的库里也有类似于sed,awk,head,tail等这样方便的文字处理函数
如果有的话,是不是用C/Fortran混合编程是不是比较容易解决数据互传的问题……

954

帖子

0

主题

0

精华

大师

F 币
184 元
贡献
75 点

规矩勋章元老勋章新人勋章水王勋章热心勋章

QQ
地板
发表于 2018-12-15 10:33:43 | 只看该作者
说真的,Fortran的文本处理能力的确不怎么样。
你用Shell处理大文件也一样的消耗内存的。并没有什么本质区别。

我对文本处理没有太大的需求,所以了解也不多。
大量的数据互传,没有什么好的思路。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-12-23 18:27

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表