I have 200 pyc files I need to convert in a folder. I am aware of converting pyc to py files through uncompyle6 -o . 31.pyc however as I have so many pyc files, this would take a long period of time. I've founds lots of documentation but not much in bulk converting to py files. uncompyle6 -o . *.pyc was not supported.
Any idea on how I can achieve this?
Might not be perfect but it worked great for me.
import os
import uncompyle6
your_directory = ''
for dirpath, b, filenames in os.walk(your_directory):
for filename in filenames:
if not filename.endswith('.pyc'):
continue
filepath = dirpath + '/' + filename
original_filename = filename.split('.')[0]
original_filepath = dirpath + '/' + original_filename + '.py'
with open(original_filepath, 'w') as f:
uncompyle6.decompile_file(filepath, f)
This is natively supported by uncompyle6
uncompyle6 -ro <output_directory> <python_directory>
-r tells the tool to recurse into sub directories.
-o tells the tool to output to the given directory.
In operating systems with shell filename expansion, you might be able to use the shell's file expansion ability. For example:
uncompyle6 -o /tmp/unc6 myfiles/*.pyc
If you need something fancier or more control, you could always write some code that does the fancier expansion. Here is the above done in POSIX shell filtering out the single file myfiles/huge.pyc:
cd myfiles
for pyc in *.pyc; do
if [[ $pyc != huge.pyc ]] ; then
uncompyle -o /tmp/unc $pyc
fi
done
Note: It seems this question was also asked in Issue on output directory while executing commands with windows batch command "FOR /R"
thank you for the code, extending it to recursively call, nested sub directories, save as uncompile.py, in the directory to be converted, to run in command prompt type "python uncomple.py" would convert pyc to py in current working directory, with error handling and if rerun skips (recovery) files checking existing py extension match
import os
import uncompyle6
#Use current working directory
your_directory = os.getcwd()
#function processing current dir
def uncompilepath(mydir):
for dirpath, b, filenames in os.walk(mydir):
for d in b:
folderpath = dirpath + '/' + d
print(folderpath)
#recursive sub dir call
uncompilepath(folderpath)
for filename in filenames:
if not filename.endswith('.pyc'):
continue
filepath = dirpath + '/' + filename
original_filename = filename.split('.')[0]
original_filepath = dirpath + '/' + original_filename + '.py'
#ignore if already uncompiled
if os.path.exists(original_filepath):
continue
with open(original_filepath, 'w') as f:
print(filepath)
#error handling
try:
uncompyle6.decompile_file(filepath, f)
except Exception:
print("Error")
uncompilepath(your_directory)
Related
This question already has answers here:
Command line execution in different folder
(3 answers)
Closed 29 days ago.
I'm trying using this code for the city wise updated population data but the python file is not writing the output results in that folder
import os
import subprocess
import glob
root_dir = "path/to/root/directory"
for dirpath, dirnames, filenames in os.walk(root_dir):
for text_file in glob.glob(os.path.join(dirpath, '*.txt')):
os.remove(text_file)
for filename in filenames:
if filename.endswith(".py"):
filepath = os.path.join(dirpath, filename)
os.system("python" + filepath)
or
subprocess.run(["python", filepath])
It is deleting the old text files but python file is not generating the updated data and in the sub process it showing in the command prompt but didn't write the text files or even creating new text files
but when I manually go to the folder and run the Python file it works fine
The issue with the line os.system("python" + filepath) is that there is no space between "python" and the file, so it will attempt to run something like pythontest.py, an invalid command. The second issue is that your program might run itself, causing an infinite loop. To fix this, check if the file is the current file with the __file__ variable before you run it. Try this code:
import os
import subprocess
import glob
root_dir = os.getcwd()
for dirpath, dirnames, filenames in os.walk(root_dir):
for text_file in glob.glob(os.path.join(dirpath, '*.txt')):
os.remove(text_file)
for filename in filenames:
if filename.endswith(".py") and os.path.join(root_dir, filename) != __file__:
filepath = os.path.join(dirpath, filename)
subprocess.run(["python", filepath])
Note that I also changed root_dir to automatically get the current directory. You can change this if you want.
Also, thanks to MrChadMWoods for helping catch an edge case in this current file detection.
You need to change the current working directory for your script to work:
Try:
subprocess.run(["python", filepath], cwd=dirpath)
This manual command is working:
!antiword "test" > "test.docx"
but the following script convert files to empty .docx files:
for file in os.listdir(directory):
subprocess.run(["bash", "-c", "antiword \"$1\" > \"$1\".docx", "_", file])
also it stores the .docx file in the previous directly e-g file is in \a\b this command will store the files to \a
I have tried many different ways including running directly on terminal adn bash loops. ony the manual way works.
Something like this should work (adjust dest_path etc. accordingly).
import os
import shlex
for filename in os.listdir(directory):
if ".doc" not in filename:
continue
path = os.path.join(directory, filename)
dest_path = os.path.splitext(path)[0] + ".txt"
cmd = "antiword %s > %s" % (shlex.quote(path), shlex.quote(dest_path))
print(cmd)
# If the above seems to print correct commands, add:
# os.system(cmd)
I'm new to stackoverflow. Sorry if this post is redundant but I haven't found the answer yet. Also, I'm fairly new to Python. I'd like to extract files from a tar file if they do not already exist in the root directory where the tar file exists. I've tried a number of versions. I think there is some redundancy in the code below, and it doesn't do what I need it to. It just keeps extracting and overwriting the existing file(s).
Files that need to be extracted will always end in "_B7.TIF". Code currently takes one argument - the full path of the directory that contains the tar file.
import os, shutil, sys, tarfile
directory = sys.argv[1]
tifFiles = []
for root, dirs, files in os.walk(directory):
for file in files:
if file.endswith(".TIF"):
# also tried tifFiles.append(file)
tifFiles.append(file.name)
elif file.endswith(".tar.gz"):
tar = tarfile.open(root + "/" + file)
for item in tar:
if str(item) in tifFiles:
print "{0} has already been unzipped.".format(str(item))
elif "_B7" in str(item):
tar.extract(item, path=root)
shutil.rmtree(root + "\gap_mask")
Here is another version that does not appear to be doing anything. I was trying to simplify...
import os, shutil, sys, tarfile
directory = sys.argv[1]
for root, dirs, files in os.walk(directory):
if file not in tarfile.getnames() and file.endswith("_B7.TIF"):
tar.extract(file, path=root)
else:
print "File: {0} has already been unzipped.".format(file)
shutil.rmtree(root + "\gap_mask")
Thank you both for your comments/suggestions. They both helped in some way. This code works for me.
import os, shutil, sys, tarfile
folder = sys.argv[1]
listFiles = os.listdir(folder)
try:
for file in listFiles:
if file.endswith(".tar.gz"):
sceneTIF = file[:-7] + "_B7.TIF"
if os.path.exists(os.path.join(folder,sceneTIF)):
print sceneTIF, "has already been extracted."
else:
tar = tarfile.open(os.path.join(folder,file))
for item in tar:
if "_B7" in str(item):
tar.extract(item, path=folder)
shutil.rmtree(os.path.join(folder,"gap_mask")
except WindowsError:
pass
Any thoughts on style/redundancy/ways to make it better? Thomas, your code was not working straight out of the box. I think it was the tarfile.open component. Probably needed tarfile.open(os.path.join(directory, archive)). I only thought of that after reworking the above though. Haven't tested. Thanks again.
os.walk iterates over directory trees, including sub-directories. From your description that is not what you want. Also, only files that are encountered earlier than your tarfiles will be considered for existence.
It is a lot easier to just check for the existence of files you encounter:
import sys
import os
import tarfile
directory = sys.argv[1]
def extract_nonexisting(archive):
for name in archive.getnames():
if os.path.exists(os.path.join(directory, name)):
print name, "already exists"
else:
archive.extract(name, path=directory)
archives = [name for name in os.listdir(directory) if name.endswith("tar.gz")]
for archive_name in archives:
with tarfile.open(archive_name) as archive:
extract_nonexisting(archive)
I am trying to include a binary file within a zip file and below is the code snippet:
I first unzip the zip contents into a temporary location and add few more files and zip it back to a new archive.
import zipfile
def test(fileName, tempDir):
# unzip the file contents,may contain binary files
myZipFile=zipfile.ZipFile(fileName,'r')
for name in myZipFile.namelist():
toFile = tempDir + '/' + name
fd = open(toFile, "w")
fd.write(myZipFile.read(name))
fd.close()
myZipFile.close()
# code which post processes few of the files goes here
#zip it back
newZip = zipfile.ZipFile(fileName, mode='w')
try:
fileList = os.listdir(tempDir)
for name in fileList:
name = tempDir + '/' + name
newZip.write(name,os.path.basename(name))
newZip.close()
except Exception:
print 'Exception occured while writing to PAR file: ' + fileName
Some of the files may be binary files. The zipping code works fine but when i try to unzip it using linux ' unzip or python's zip module , i get the below error:
zipfile corrupt. (please check that you have transferred or
created the zipfile in the appropriate BINARY mode and that you have
compiled UnZip properly)
And am using python 2.3
What's going wrong here ?
You might want to upgrade, as Python 2.3 is really outdated. 2.7.3 is the latest one from the 2.x-versions and 3.2.3 the latest python version.
See docs.python.org:
| extractall(self, path=None, members=None, pwd=None)
| Extract all members from the archive to the current working
| directory. `path' specifies a different directory to extract to.
| `members' is optional and must be a subset of the list returned
| by namelist().
(New in version 2.6)
Take a look at Zip a folder and its content.
You might also be interested in distutlis.archive_util.
Hmm not sure if its a bug in python 2.3. Current work environment do not allow me to upgrade to a higher version of python :-( :-( :-(
The below workaround worked:
import zipfile
def test(fileName, tempDir):
# unzip the file contents,may contain binary files
myZipFile=zipfile.ZipFile(fileName,'r')
for name in myZipFile.namelist():
toFile = tempDir + '/' + name
# check if the file is a binary file
#if binary file, open it in "wb" mode
fd = open(toFile, "wb")
#else open in just "w" mode
fd = open(toFile, "w")
fd.write(myZipFile.read(name))
fd.close()
myZipFile.close()
# code which post processes few of the files goes here
#zip it back
newZip = zipfile.ZipFile(fileName, mode='w')
try:
fileList = os.listdir(tempDir)
for name in fileList:
name = tempDir + '/' + name
newZip.write(name,os.path.basename(name))
newZip.close()
except Exception:
print 'Exception occured while writing to PAR file: ' + fileName
I have a directory c:/go , inside go there is tons of folders, subfolders and files.
I need to find inside go, files that start with net*.inf and oem*.inf , and copy the folder, subfolders and all files where they are to another palce at c:/
It must be something automatic using windows... like batch script, c++, python...vbs pleasee!! thanks in advance
From the command line, one way is to combine xcopy with a for loop:
for /D %i in (net oem) do xcopy /s c:\go\%i*.inf c:\go2\
In a batch file just replace %i with %%i.
The xcopy technique in #ars' answer is obviously simpler for your situation if it is appropriate for you. However, below is a Python implementation. It will make sure the target directory is there and create it if it isn't:
#!python
import os
import re
import shutil
def parse_dir(src_top, dest_top):
re1 = re.compile("net.*\.inf")
re2 = re.compile("oem.*\.inf")
for dir_path, dir_names, file_names in os.walk(src_top):
for file_name in file_names:
if re.match(re1, file_name) or re.match(re2, file_name):
target_dir = dir_path.replace(src_top, dest_top, 1)
if not os.path.exists(target_dir):
os.mkdir(target_dir)
src_file = os.path.join(dir_path, file_name)
dest_file = os.path.join(target_dir, file_name)
shutil.copyfile(src_file, dest_file)
src_top = "\\go"
dest_top = "\\dest"
parse_dir(src_top, dest_top)
Improvements are probably possible, but this should get you started if you want to go this way.