【问题标题】:Convert python2 shebang to python3 shebang for a set of files将一组文件的python2 shebang转换为python3 shebang
【发布时间】:2023-11-28 18:09:01
【问题描述】:

我将我的 python 脚本从版本 2.7 升级到 3.6 - 所有脚本都有 python2 shebang 即#!/usr/bin/python

我想用python脚本把它改成python3 shebang #!/usr/bin/python3

【问题讨论】:

  • 你能告诉我们你到目前为止做了什么吗?我们可以帮助您,但不会为您建造任何东西!
  • @jonas 感谢您的评论,我找到了解决方案并自己回答了问题

标签: python-3.x python-2.7 upgrade shebang


【解决方案1】:

先决条件:

  1. parseshebang - pip install parse-shebang
  2. autopep8 - pip install autopep8

库:

import parseshebang
import os, sys
import subprocess

变量:

pathToScripts = '/path/to/python/folder/'
maxLines = 5 # max empty lines before shebang occurs
replacementText = '#!/usr/bin/python3' #new shebang

函数-replace_first_line:

def replace_first_line( src_filename, target_filename, replacement_line):
    f = open(src_filename)
    first_line = f.readline()
    i = 0 
    while True:
        i+=1
        #check if the first line starts with a shebang
        if first_line.strip().startswith('#!'):
            break
        #check if the line is empty
        if first_line.strip() == '':
            #because line is empty, we read the next line
            first_line = f.readline()
            if first_line is None:
                #skip the file if there is nothing to read
                return
            if i >= maxLines:
                #The file contains more than 5 empty lines
                #Copy the file as it is
                break
    remainder = f.read()
    t = open(target_filename,"w")
    t.write(replacement_line + "\n")
    t.write(remainder)
    t.close()

主要功能:

#Loop through all the .py files in the directory mentioned earlier
for file in [f for f in os.listdir(pathToScripts) if f.endswith('.py')]:
    shebang = parseshebang.parse(os.path.join(pathToScripts,file))
    if shebang and shebang[0] == replacementText.replace('#!',''):
        #The file already contains shebang, skip
        continue
    elif shebang:
        #if any shebang is present, replace the shebang with the new one
        #Note that we are sending the same path as source and target, 
        #so the changes will be overwritten - change accordingly
        replace_first_line(os.path.join(pathToScripts,file), os.path.join(pathToScripts,file), replacementText)

#to fix the tab error - inconsistent use of tabs
subprocess.call(['autopep8 --in-place --list-fixes --recursive ', pathToScripts], shell=True)

确定!

PS:这可能是一个麻烦的解决方案,但它确实有效。如有错误请见谅。

【讨论】: