Moving unsupported file extensions by python - python

I'm trying to move files from one directory to another using Python - spyder.
My file extension is *.OD which python does not support or read.
I have tried using the wildcard and leaving out the file extension (which does not work). Another file extension cannot be used for this particular file.
Moving python supported extensions such as .txt and .csv works fine.
import shutil
source = '//Original_Filepath/Extract*.od'
target = '//NewFilePath/Extract_*.od'
shutil.copy(source, target)
There are no errors, it just doesn't move/copy the file.
Thanks,

There are a couple of basic mistakes with how you're trying to copy the files. With shutil.copy you should not specify a glob, but instead the exact source and destination.
If instead you want to copy a set of files from one directory to another and (presuming the added underscore isn't a mistake) change the target, then you should try using pathlib in combination with shutil (and re if needed).
pathlib - Object-oriented filesystem paths
Try adapting this:
import pathlib
import shutil
import re
source = pathlib.Path('//Original_Filepath') # pathlib takes care of end slash
source_glob = 'Extract*.od'
target = pathlib.Path('//NewFilePath')
for filename in source.glob(source_glob):
# filename here is a Path object as well
glob_match = re.match(r'Extract(.*)\.od', filename.stem).group(1)
new_filename = "Extract_{}.od".format(glob_match)
shutil.copy(str(filename), str(target / new_filename)) # `/` will create new Path
If you're not interested in editing the target nor using any other advanced feature that pathlib provides then see Xukrao's comment.

Thank you all for your help. Much appreciated! :)
I was also able to copy the file with the below as well (a bit simpler).
I left out the * and used a date string instead.
import shutil
from datetime import datetime
now = datetime.now()
Org_from=os.path.abspath('//Original FilePath')
New_to=os.path.abspath('//New Path')
shutil.copy(os.path.join(org_from, 'File_' + now.strftime("%Y%m%d") + '.od'), os.path.join(New_to, 'File_' + now.strftime("%Y%m%d") + '.od'))
Cheers,
Jen

Related

How to move files with a specified extension to a new folder in Python

I am trying to move files within a folder to another folder whilst only moving files with the extensions .bmp.
I am using the shutil.move() method and it works when I don't specify file types but once I do it stops working. I have tried to debug it but cant figure out why my code isn't working. I dont get any tracebacks, nothing happens.
import time
import os
import shutil
from datetime import datetime
today = datetime.now()
src = "."
dst = ('C:\Python\Image Compressor\File Saving\Archive\BDB040803_St14_' +
today.strftime('%d_%m_%Y'))
files = os.listdir(src)
for file in src:
if file.endswith(".bmp"):
shutil.move(os.path.join(src,file), os.path.join(dst,file))
Replace src by files in line:
for file in src:
In case you're interested in an alternative approach (yours isn't bad, this isn't meant as criticism).
You could use pathlib:
from pathlib import Path
from datetime import date
src = Path()
dst = Path(
r"C:\Python\Image Compressor\FileSaving\Archive\BDB040803_St14_"
+ date.today().strftime("%d_%m_%Y")
)
for file in src.glob("*.bmp"):
file.replace(dst / file.name)
.glob allows you to fetch path/file-names that match patterns. The pattern structures aren't as powerful as regex, but can still be pretty helpful. You could also use the glob module directly.
.replace takes over shutil.move's job.
Okay so I have finally solved my problem. I will post my code here for a reference for anyone else who runs into this problem. #siloob thank you for your input, you were correct with your correction but I still had tracebacks after this so I had a few more changes to make.
I needed my bmp files to transfer and not my .py files so I added an if statement with a continue to skip over any files with .py. This solved my problem and only transferred the bmp files.
import time
import os
import shutil
from datetime import datetime
today = datetime.now()
src = "."
dst = ('C:\Python\Image Compressor\File Saving\Archive\BDB040803_St14_' +
today.strftime('%d_%m_%Y'))
files = os.listdir(src)
for file in files:
if file.endswith(".py"):
continue
else:
shutil.move(os.path.join(src,file), os.path.join(dst,file))

How to display a variable without a specific part?

So, i have a variable, for example dir = "Crypter.aes". I need to variable like dir, but without .aes. What gotta I do for that? I use directory parser, that make many dir with file name in that directory, and for each file I need to remove a certain part at the end - .aes
This is a task for the os.path module in the standard library.
import os.path
dir, _ = os.path.splitext("Crypter.aes")
If you're working a lot with file paths, you also might want to take a look at the pathlib module.
from pathlib import Path
dir = Path("Crypter.aes").stem

How can I read files with similar names on python, rename them and then work with them?

I've already posted here with the same question but I sadly I couldn't come up with a solution (even though some of you guys gave me awesome answers but most of them weren't what I was looking for), so I'll try again and this time giving more information about what I'm trying to do.
So, I'm using a program called GMAT to get some outputs (.txt files with numerical values). These outputs have different names, but because I'm using them to more than one thing I'm getting something like this:
GMATd_1.txt
GMATd_2.txt
GMATf_1.txt
GMATf_2.txt
Now, what I need to do is to use these outputs as inputs in my code. I need to work with them in other functions of my script, and since I will have a lot of these .txt files I want to rename them as I don't want to use them like './path/etc'.
So what I wanted was to write a loop that could get these files and rename them inside the script so I can use these files with the new name in other functions (outside the loop).
So instead of having to this individually:
GMATds1= './path/GMATd_1.txt'
GMATds2= './path/GMATd_2.txt'
I wanted to write a loop that would do that for me.
I've already tried using a dictionary:
import os
import fnmatch
dict = {}
for filename in os.listdir('.'):
if fnmatch.fnmatch(filename, 'thing*.txt'):
examples[filename[:6]] = filename
This does work but I can't use the dictionary key outside the loop.
If I understand correctly, you try to fetch files with similar names (at least a re-occurring pattern) and rename them. This can be accomplished with the following code:
import glob
import os
all_files = glob.glob('path/to/directory/with/files/GMAT*.txt')
for file in files:
new_path = create_new_path(file) # possibly split the file name, change directory and/or filename
os.rename(file, new_path)
The glob library allows for searching files with * wildcards and makes it hence possible to search for files with a specific pattern. It lists all the files in a certain directory (or multiple directories if you include a * wildcard as a directory). When you iterate over the files, you could either directly work with the input of the files (as you apparently intend to do) or rename them as shown in this snippet. To rename them, you would need to generate a new path - so you would have to write the create_new_path function that takes the old path and creates a new one.
Since python 3.4 you should be using the built-in pathlib package instead of os or glob.
from pathlib import Path
import shutil
for file_src in Path("path/to/files").glob("GMAT*.txt"):
file_dest = str(file_src.resolve()).replace("ds", "d_")
shutil.move(file_src, file_dest)
you can use
import os
path='.....' # path where these files are located
path1='.....' ## path where you want these files to store
i=1
for file in os.listdir(path):
if file.endswith(end='.txt'):
os.rename(path + "/" + file, path1 + "/"+str(i) + ".txt")
i+=1
it will rename all the txt file in the source folder to 1,2,3,....n.txt

How to normalize a relative path using pathlib

I'm trying to use relative paths in Python, and I want to put my csv files in a separate folder from my python code.
My python program is in the following folder:
G:\projects\code
I want to read this file which is one level up:
G:\projects\data\sales.csv
How do I specify a path using pathlib that is one level up from my current working folder? I don't want to change the current working folder.
I tried this:
from pathlib import Path
file = Path.cwd() /'..'/'data'/'sales.csv'
But now the 'file' variable equals this:
'G:/projects/code/../data/sales.csv'
I read through the docs and either it isn't explained there or I'm just missing it.
Although it's not a problem that your path includes '..' (you can still use this path to open files, etc. in Python), you can normalize the path using resolve():
from pathlib import Path
path = Path.cwd() / '..' / 'data' / 'sales.csv'
print(path) # WindowsPath('G:/projects/code/../data/sales.csv')
print(path.resolve()) # WindowsPath('G:/projects/data/sales.csv')
NB: I personally would name a variable that contains a path path, not file. So you could later on do file = open(path).
print(
Path(__file__).parent, # the folder
Path(__file__).parent.parent, # the folder's parent
sep='\n'
)
print(
Path(
Path(__file__).parent.parent, 'hello.py'
)
)
results in
C:\Users\isik\Desktop\Python\MessAround\project\module
C:\Users\isik\Desktop\Python\MessAround\project
C:\Users\isik\Desktop\Python\MessAround\project\hello.py
with this file structure
-project
-module
-__init__.py
-hello.py
-__init__.py
while the code is located inside project.module.__init__.py
Do you mean "read my csv files"?
The import keyword has a different meaning in Python (you import only other Python modules).
In any case, in order to read a file located one folder above your Python file, you can use this:
import os
filePath = os.path.dirname(__file__)+'/../'+fileName
fileDesc = open(filePath)
fileData = fileDesc.read()
fileDesc.close()
...
here is an example I used:
import json
from pathlib import Path
def read_files(folder_name, file_name):
base_path = Path.cwd().joinpath('configs','resources')
path = base_path.joinpath(folder_name,file_name)
open_file = open(path,'r')
return json.load(open_file.read())
This is pretty old, but I happened on it looking for something else.
Oddly you never got a direct, obvious, answer -- you want the parent property:
from pathlib import Path
file = Path.cwd().parent / 'data' / 'sales.csv'
Note that some of the answers that say you want __file__ rather than the current working directory may be correct (depending on your use case), in which case it's:
from pathlib import Path
file = Path(__file__).parent.parent / 'data' / 'sales.csv'
(parent of the python file is the code dir, parent of that is the projects dir.
However, It's not great practice to refer to your data by its relative path to your code -- I think using the cwd is a better option -- though what you should do is pass the path to the data in to the script via sys.argv.

os.path moving through directories

i have this structure in my code.
app
src
script.py
data
data.ptk
i need to open the file "data.ptk" from "scrip.py", using os.path i'm able to extract the script path.
my_path = os.path.abspath(os.path.dirname(__file__))
But flowing the structure i need to go back 2 directories and then enter the "data" directory to open the file.
The easy way would be to decompose the string my_path with a split("/"), remove the last 2 words and add "data" ...
But I do not think it's the right way
The script.py need to be independent of the OS, that is the reason i'm not able to "hard code" the directory where de pkl file is placed
Any suggestions? thanks.
To elaborate on my comment more, you can see the documentation for pathlib here: https://docs.python.org/3/library/pathlib.html?highlight=pathlib#module-pathlib. It is a stock part of python3 (not sure about python2). I think the following would work:
from pathlib import Path
scriptPath = Path(__file__).absolute() # the absolute() is not strictly necessary
srcPath = scriptPath.parent
appPath = srcPath.parent
commonDirectory = appPath.parent # this could have been shortened with scriptPath.parent.parent.parent
dataPath = commonDirectory / 'data'
dtkFile = dataPath / 'data.ptk'

Categories

Resources