计算化学公社

标题: 怎样让Multiwfn批处理时按一定顺序进行 [打印本页]

作者
Author:
chuan437    时间: 2023-3-12 11:45
标题: 怎样让Multiwfn批处理时按一定顺序进行
使用Multiwfn在linux下的批处理功能时(http://sobereva.com/612),遇到一个问题:
我的文件都是以文件名+数字后缀的形式命名的,例如pfoa_1, pfoa_2……
但是Multiwfn批处理时,不是按照文件名的顺序执行(如图),这给后续处理带来不便,请问如何解决这个问题。

作者
Author:
sobereva    时间: 2023-3-12 11:57
产生文件的时候把十位数用0补齐
作者
Author:
snljty2    时间: 2023-3-12 12:29
这本来就是按文件名顺序的字典排序法...比如字符'3'在字符'4'前面,39.fch和3.fch比,英文句号'.'的ASCII码是46,数字'3'是51,点在数字前面,所以_3.fch就应该排在_39.fch和_40.fch之间。如果你想按数值大小排序而不是按字符串的字典排序法,要么如卢老师说,用shell的printf之类的命令让前一步固定输出几位数字,不足的用0补全,比如_03.fch,要么循环用ls -v,比如
  1. for filename in `ls -v *.fch`
  2. do
  3.     Multiwfn $filename << EOF
  4. # Multiwfn commands
  5. EOF
  6. done
复制代码

作者
Author:
neocc    时间: 2023-3-12 16:50
shell(bash)建议后面通过管道加个sort -V或者sort -n
效果跟三楼一样
  1. ls -v
复制代码


  1. ls *.fch | sort -V
复制代码

作者
Author:
chuan437    时间: 2023-3-12 17:05
snljty2 发表于 2023-3-12 12:29
这本来就是按文件名顺序的字典排序法...比如字符'3'在字符'4'前面,39.fch和3.fch比,英文句号'.'的ASCII码 ...

好的,谢谢。还是你的第二个方法简捷,赞
本来我按照社长的建议,用0补齐文件名,python脚本如下:
import os
filePath='C:\\Users\\Administrator\\Desktop\\1'
def fileNameAlign(filePath,connector='_'):
    os.chdir(filePath)
    fileList=[i for i in os.listdir() if connector in i]
    print(fileList)
    for i in fileList:
        name,numType=i.split(connector)
        num,typeName=numType.split('.')
        while len(num)<3:
            num='0'+num
            print()
        os.rename(i,name+'_'+num+'.'+typeName)
fileNameAlign(filePath,connector='_')
#使用时需要设置文件的路径,如果是Gaussian批量保存的出来的多个文件,用默认的下划线_作为文件名连接符即可。
作者
Author:
snljty2    时间: 2023-3-12 17:37
本帖最后由 snljty2 于 2023-3-13 09:19 编辑
chuan437 发表于 2023-3-12 17:05
好的,谢谢。还是你的第二个方法简捷,赞
本来我按照社长的建议,用0补齐文件名,python脚本如下:
imp ...

4L的也是一种方式。另外Python里肯定不用这么麻烦。可以找本教材看看Python格式化字符串的部分。就我所知至少有三种比较简单而且常见的写法:
第一种,C语言风格的%格式化字符串,最古老的一种:
  1. for i in range(1, 1 + 99):
  2.     print("pfoa_%02d.fch" % i)
复制代码

第二种,用Python2.6和3.0新加的string类的的format方法:
  1. for i in range(1, 1 + 99):
  2.     print("pfoa_{:02d}.fch".format(i))
复制代码

第三种:用Python 3.6开始引入的f-string
  1. for i in range(1, 1 + 99):
  2.      print(f"pfoa_{i:02d}.fch")
复制代码

可能还有一些使用string.Template之类的方法,不深究了。
顺便说一下上面Shell的写法
  1. for i in `seq 1 99`
  2. do
  3.     printf "pfoa_%02d.fch\n" $i
  4. done
复制代码

作者
Author:
chuan437    时间: 2023-3-12 18:24
snljty2 发表于 2023-3-12 17:37
4L的也是一种方式。另外Python里肯定不用这么麻烦。可以找本教材看看Python格式化字符串的部分。就我所知 ...

赞,你的代码确实很pythonic!




欢迎光临 计算化学公社 (http://ccc.keinsci.com/) Powered by Discuz! X3.3