how to get name of a file in directory using python - python

There is an mkv file in a folder named "export". What I want to do is to make a python script which fetches the file name from that export folder.
Let's say the folder is at "C:\Users\UserName\Desktop\New_folder\export".
How do I fetch the name?
I tried using this os.path.basename and os.path.splitext .. well.. didn't work out like I expected.

os.path implements some useful functions on pathnames. But it doesn't have access to the contents of the path. For that purpose, you can use os.listdir.
The following command will give you a list of the contents of the given path:
os.listdir("C:\Users\UserName\Desktop\New_folder\export")
Now, if you just want .mkv files you can use fnmatch(This module provides support for Unix shell-style wildcards) module to get your expected file names:
import fnmatch
import os
print([f for f in os.listdir("C:\Users\UserName\Desktop\New_folder\export") if fnmatch.fnmatch(f, '*.mkv')])
Also as #Padraic Cunningham mentioned as a more pythonic way for dealing with file names you can use glob module :
map(path.basename,glob.iglob(pth+"*.mkv"))

You can use glob:
from glob import glob
pth ="C:/Users/UserName/Desktop/New_folder/export/"
print(glob(pth+"*.mkv"))
path+"*.mkv" will match all the files ending with .mkv.
To just get the basenames you can use map or a list comp with iglob:
from glob import iglob
print(list(map(path.basename,iglob(pth+"*.mkv"))))
print([path.basename(f) for f in iglob(pth+"*.mkv")])
iglob returns an iterator so you don't build a list for no reason.

I assume you're basically asking how to list files in a given directory. What you want is:
import os
print os.listdir("""C:\Users\UserName\Desktop\New_folder\export""")
If there's multiple files and you want the one(s) that have a .mkv end you could do:
import os
files = os.listdir("""C:\Users\UserName\Desktop\New_folder\export""")
mkv_files = [_ for _ in files if _[-4:] == ".mkv"]
print mkv_files

If you are searching for recursive folder search, this method will help you to get filename using os.walk, also you can get those file's path and directory using this below code.
import os, fnmatch
for path, dirs, files in os.walk(os.path.abspath(r"C:/Users/UserName/Desktop/New_folder/export/")):
for filename in fnmatch.filter(files, "*.mkv"):
print(filename)

You can use glob
import glob
for file in glob.glob('C:\Users\UserName\Desktop\New_folder\export\*.mkv'):
print(str(file).split('\')[-1])
This will list out all the files having extention .mkv as
file.mkv, file2.mkv and so on.

From os.walk you can read file paths as a list
files = [ file_path for _, _, file_path in os.walk(DIRECTORY_PATH)]
for file_name in files[0]: #note that it has list of lists
print(file_name)

Related

read a zipfile without knowing file name in python

I have a zip file in a directory. I want to read out the contents of the zipfile and after this move its content to other directories to auto sort my zipped files. thing is, the name of these zipfiles will change everytime.
I learned about glob being able to handle the asterix for this normally, but it doesn't work with the zipfile import.
I tried:
from zipfile import ZipFile
from glob import glob
path_to_zip = glob(r"C:\me\Python\map_dumper\*.zip")
with ZipFile(path_to_zip, "r") as read_zip:
ZipFile.namelist()
This gives me an AttributeError:'list' object has no attribute 'seek'
anyone know of another solution for this?
glob.glob gives you list of filenames compliant with what you specify, for example
glob(r"C:\me\Python\map_dumper\*.zip")
is list of all zip files inside map_dumper catalog, you might use for loop to apply your action to every such file following way
from zipfile import ZipFile
from glob import glob
files_list = glob(r"C:\me\Python\map_dumper\*.zip")
for path_to_zip in files_list:
with ZipFile(path_to_zip, "r") as read_zip:
ZipFile.namelist()

Delete file by non standard extension

I know how to delete files by extension but what if my files are looking like this:
update_24-08-2022_14-54.zip.001
Where last 3 digits can be between 001-029
Here is code that I'm using for standard zip files
files_in_directory = os.listdir(directory)
filtered_files = [file for file in files_in_directory if file.endswith(".zip")]
for file in filtered_files:
path_to_file = os.path.join(directory, file)
os.remove(path_to_file)
Assuming the double extensions are of the form .zip.xyz, with xyz being triple digits, you can use globbing:
import glob
import os
for path in glob.glob('*.zip.[0-9][0-9][0-9]'):
os.remove(path)
(As a usual precaution, check first, by replacing os.remove with print).
If you have a specific directory, its name stored in directory, you can use:
import glob
import os
for path in glob.glob(os.path.join(directory, '*.zip.[0-9][0-9][0-9]')):
os.remove(path)
There is no need to join the directory and path inside the for loop (as is the case in the question): path itself will already contain the directory name.

Use glob to match files without a file extension

I am trying to use glob to match all the files in a folder. All the files start with the same word but I forgot to include .txt at the end of them. Is there a way to write the code to get all of these files despite the fact there is no file extension in my directory?
I'm assuming you want to add a .txt file extension from the way you worded your question. You can use a wildcard character (*) anywhere in your glob expression
import glob
import shutil
for file in glob.glob('/path/to/files/commonWord*'):
shutil.move(file, file + '.txt')
not sure if that is what you want, but this will get all the files/folders that start with the word "california" in the same directory.
So if no folders start with "california" in your directory this will do it
import glob, os
for file_ in glob.glob('california*'):
os.rename(file_, file_+'.csv')
output1: ['california_housing_train', 'california_housing_test']
output2: ['california_housing_train.csv', 'california_housing_test.csv']
You can take them all and then check by regex whether or not it has an extension and add the file to a list or whatever you want.
import glob
import re
files = glob.glob('*')
for file in files:
if not re.findall(r'.*\.[a-z]+',file):
print(file)

Python delete file in multiple folders

In multiple folders I have a file called _status.json
e.g.:
C:\Users\Me\.fscrawler\Folder1\_status.json
C:\Users\Me\.fscrawler\Folder2\_status.json
....
C:\Users\Me\.fscrawler\*\_status.json
I want to write a short python code, to delete all those files.
I already tried the following code, but it does not work. I dont know why, but I think the solution is pretty easy
import os
os.remove(C:\Users\Me\.fscrawler\*\_status.json)
You will have to walk through all the subfolders to find and delete the file.
for root, dirs, files in os.walk(folder_path):
for name in files:
if name == '_status.json':
#delete the file
I would look into the glob module, and use it to find the files:
example:
import glob
relative_path_to_files = glob.glob('**/_status.json', recursive=True)
then you can operate on the list as you wish :)
Edit:
relative_path_to_files is a list, so you have to iterate over its elements and operate on them:
here is a complete example to find all _status.json in the current directory and its sub-tree recursively:
import glob
import os
for f in glob.glob('**/_status.json', recursive=True):
os.remove(f)

Rename Single .txt File In Multiple Subdirectories

I have ~60 subdirectories in a single directory. Each of these contain thousands of files, but they all contain a file named test_all_results.txt.
What I would like to do is to rename each test_all_results.txt file so that it now has the name:
foldername_all_results.txt
What is the best way to do this?
Easily accomplished using Python os interface.
Assuming you are currently in the main directory:
import os
#get a list of all sub directories
subdir = os.listdir()
for dir in subdir:
if os.path.isdir(dir): #check if directory
os.chdir(dir) #move to sub directory
os.rename('test_all_results.txt', 'foldername_all_results.txt')
os.chdir('..') #return to main directory
Using python in Linux, make this:
import os
os.system("mv old_name.txt new_name.txt")
You can automatize with a loop, renaming all filenames.
You can do:
(change your code accordingly)
import os
# current directory is the target
direct = "."
for path, dirs, files in os.walk(direct):
for f in files:
if os.path.splitext(f)[0] == "test_all_results.txt":
os.rename(os.path.join(path, f), os.path.join(path, "foldername_all_results.txt"))
There's an answer that tells you to use the os.system() method, if you do decide to call Linux commands from Python, I'd advise that you use the subprocess module instead.
Here's how you'd run the mv command with two arguments using subprocess.call:
import subprocess
subprocess.call(["mv", "filename.txt", "new-name.txt"])
INFO: here's an old (but relevant) article that explains why it's dangerous to use these methods.
Good luck.

Categories

Resources