I am intermediate when it comes to python but when it comes to modules I struggle. I'm working on a project and I'm trying to assign a variable to a random directory or file within the current directory (any random thing within the directory). I would like it to just choose any random thing in that directory and then assign it to a variable.
The product should end up assigning a variable to a random object within the working directory. Thank you.
file = (any random file in the directory)
Edit: This works too
_files = os.listdir('.')
number = random.randint(0, len(_files) - 1)
file_ = _files[number]
Thank you everyone that helped :)
Another option is to use globbing, especially if you want to choose from some files, not all files:
import random, glob
pattern = "*" # (or "*.*")
filename = random.choice(glob.glob(pattern))
You can use
import random
import os
# random.choice selects random element
# os.listdir lists in current directory
filename=""
# filter out directories
while not os.path.isfile(filename):
filename=random.choice(os.listdir(directory_path))
with open(filename,'r') as file_obj:
# do stuff with file
_files = os.listdir('.')
number = random.randint(0, len(_files) - 1)
file_ = _files[number]
Line by line order:
It puts all the files in the directory into a list
Chooses a random number between 0 and the length of the directory - 1
Assigns _file to a random file
Here is an option to print and open a single random file from directory with mulitple sub-directories.
import numpy as np
import os
file_list = [""]
for root, dirs, files in os.walk(r"E:\Directory_with_sub_directories", topdown=False):
for name in files:
file_list.append(os.path.join(root, name))
the_random_file = file_list[np.random.choice(len(file_list))]
print(the_random_file)
os.startfile(the_random_file)
Related
As the title says , in a folder with multiple PDF files i have to move the ones that start with the same 13 characters ( considered as doubles)(One of the doubles not all of them) to a folder named 'doubles' in the same original folder.
The PDF files are already sorted but i would love to get a line to sort them by name first.
Here's my attempt:
import os
import shutil
os.chdir('Path of the folder')
# replace '\' by '/'
for file in os.listdir()
if file == 'doubles' :
continue
#to skip the folder for the doubles
if file.startswith(point to the next file[0-12]) :
Shutil.move(file.path,'doubles path')
Thanks in advance
You can use the collections package to find duplicates. Then get the index of any of those files and move it:
import os
import shutil
import collections
path = "yourPath"
pathDouble = os.path.join(path, 'double')
origFiles = os.listdir(path)
cutFiles = [file[:13] for file in os.listdir(path)]
numbers = collections.Counter(cutFiles)
if not os.path.exists(pathDouble):
os.makedirs(pathDouble)
for double, doubleCount in reversed(numbers.items()):
if doubleCount == 1:
break
else:
idx = cutFiles(double)
shutil.move(os.path.join(path, origFiles[idx]), os.path.join(pathDouble, origFiles[idx]))
Here's another try, this time it works better :) (as far as the tests that i did go :) )
import os
import shutil
import collections
import pathlib
paths='Path here'
origFile=os.listdir(paths)
cutFiles=[file[0:3] for file in origFile]
c=0
for path in pathlib.Path(paths).iterdir():
if path.is_file():
c+= 1
#to count how many files in the folder for a loop
for i in range (0,c+1) :
#+1 for the double folder , the system is only counting files
if(cutFiles[i]==cutFiles[i+1]) :
shutil.move(os.path.join(paths,origFile[i]),'double folder path')
I got this code and i need to take the first path of a file and the files name an have put it as a string
from pathlib import Path
from os import walk
import os
from posixpath import dirname
f = []
jhon = r'C:\Users\ioshu\Desktop\you'
for (dirpath, dirnames, filenames) in walk(jhon):
f.extend(filenames)
f.extend(dirnames)
break
Ben1= filenames[:1]
Ben2= dirpath[:2]
dataFolder = Path(r'C:\Users\ioshu\Desktop\you')
print(Ben1 , dataFolder)
print(dataFolder)
The print (ben1, dataFolder)
the output" of that file is
C:\Users\ioshu\Desktop\you ['07a5iya4vfm91-DASH_720.mp4']
The problem is that i need the out put to be like this C:\Users\ioshu\Desktop\you\0q74nqluycm91-DASH_720
Using walk will walk the whole tree, which is overkill for your needs. You can simply
first_file_name = os.listdir('/etc')[0]
if you are sure there are only files, or:
import os
path = '/etc' # any path you want
first_file = None
for i in os.listdir(path):
file_path = os.path.join(path, i)
if os.path.isfile(file_path):
first_file = file_path
break # assuming you don't need to sort the names
Always use os.path.join to join paths, works on Linux, Windows, MacOS and any other supported platform.
PS: Ben1 = filenames[:1] returns a list with one element, not the element. If you need the element then: Ben1 = filenames[0].
PS2: If you want to use pathlib then dataFolder / filenames[0] or something will help.
So I've been working on this for quite a while now..
The incoming mail (paper) is scanned using a Xerox WorkCentre.
On the screen we select the matching scan folder for any customer/vendor (4 digit number).
So any invoice by vendor x is stored in a specific folder.
Now we'd like to rename the pdf-file by prepending the matching customer-ID (4 digits) to the file, which happens to be the name of the parent folder where the pdf is stored in.
On our server we have a folder structure where all the scans are stored like this:
S:/Scan/[4 digit number]/filename.pdf
e.g. S:/Scan/9020/
where the contents is like
doc_12345.pdf
doc_12346.pdf
[...]
Now I'd like to prepend the parent folder name to any file like this:
S:/Scan/9020/doc_12345.pdf becomes S:/Scan/9020/9020_doc_12345.pdf
S:/Scan/9021/doc_12346.pdf becomes S:/Scan/9021/9021_doc_12345.pdf
After the file has been renamed, it should be moved to a common folder like:
S:/Scan/Renamed/
I would appreciate any ideas :)
Try this:
import os
import glob
import pathlib
inp_dir = 'S:/Scan/'
out_dir = 'S:/Scan/Renamed/'
folder_list = [i for i in pathlib.Path(inp_dir).iterdir() if i.is_dir()]
for cust in folder_list:
flist = glob.glob(str(cust) + '/*.pdf')
flist = [pathlib.Path(i) for i in flist]
for file in flist:
new_name = f'{cust.name}_{file.name}'
os.rename(str(file), f'{out_dir}{new_name}')
import os
import shutil
source = 'S:/Scan/Source/'
target = 'S:/Scan/Renamed/'
for dpath, dnames, fnames in os.walk(source):
for f in fnames:
n = dpath.rsplit('/',2) [-1]
os.chdir(dpath)
if not f.startswith(n):
os.rename(f, f.replace(f, n+'_'+f))
nf = dpath+"/"+n+'_'+f
shutil.move(nf, target)
That's what I've got so far.
Seems to work.
I've multiple sub-folders and each sub-folder has multiple files. I need to select the sub-folder randomly and then need to select a random file in that sub-folder. Let's say I've five folders A, B, C, D, E, and each folder contains another folder named data and this data folder contains multiple files. I need to pick the folder randomly from the five folders and then open the data folder and finally randomly select a file.
Keep the folder names in a list.
import random
import os
folders = [0,1,2,3,4]
selected_folder = random.choice(folders)
path = selected_folder+"/data"
Now to take random file from the path, do random.choice() and pass the list of files in that path.
Use os.listdir(path) to get the list of files.
import os
import random
path = os.getcwd()
def getRandomFile(path):
randomDir = random.choice([(x) for x in list(os.scandir(path)) if x.is_dir()]).name
randomFile = random.choice([f for f in list(os.scandir(randomDir + "\\data\\"))]).name
return randomFile
print(getRandomFile(path))
Try this: (Python file must be in the same main folder as those 5 folders)
import os,random
lst=list(filter(lambda x: os.path.isdir(x), os.listdir('.'))) //get folder list
folder=random.choice(lst) //select random folder
os.chdir(os.path.join(os.path.dirname(__file__), folder, 'data')) // goto random folder/data
lst=list(filter(lambda x: os.path.isfile(x), os.listdir('.'))) //get file list
file=random.choice(lst) //get random file
print(file)
As I understand, you actually need 4 functions to build your block of code:
os.listdir(path) which list all files and directories at a location
os.path.isdir(path) to check if a element in a location is a directory
os.path.isfile(path) idem with a files
random.randrange(X) to find a random number in the range [0; X[
I'm sure you can find easily the doc concerning those functions as they are all in the standard library of python. Anyway here is your code:
import os
import random
path = "/home/johndoe/"
dirs = list(filter(lambda dir: os.path.isdir(os.path.join(path, dir)), os.listdir(path)))
dir_chosen = dirs[random.randrange(len(dirs))]
files_path = os.path.join(path, dir_chosen, "data")
files = list(filter(lambda file: os.path.isfile(os.path.join(files_path, file)), os.listdir(files_path)))
file_chosen = files[random.randrange(len(files))]
print("the file randomly chosen is: {}".format(os.path.join(files_path, file_chose )))
You can also check about os.path.join(a, b) if you don't know about it but it is basically equivalent to a + '/' + b on UNIX and a + '\' + b on Windows.
I'm trying to rename multiple files in a directory using this Python script:
import os
path = '/Users/myName/Desktop/directory'
files = os.listdir(path)
i = 1
for file in files:
os.rename(file, str(i)+'.jpg')
i = i+1
When I run this script, I get the following error:
Traceback (most recent call last):
File "rename.py", line 7, in <module>
os.rename(file, str(i)+'.jpg')
OSError: [Errno 2] No such file or directory
Why is that? How can I solve this issue?
Thanks.
You are not giving the whole path while renaming, do it like this:
import os
path = '/Users/myName/Desktop/directory'
files = os.listdir(path)
for index, file in enumerate(files):
os.rename(os.path.join(path, file), os.path.join(path, ''.join([str(index), '.jpg'])))
Edit: Thanks to tavo, The first solution would move the file to the current directory, fixed that.
You have to make this path as a current working directory first.
simple enough.
rest of the code has no errors.
to make it current working directory:
os.chdir(path)
import os
from os import path
import shutil
Source_Path = 'E:\Binayak\deep_learning\Datasets\Class_2'
Destination = 'E:\Binayak\deep_learning\Datasets\Class_2_Dest'
#dst_folder = os.mkdir(Destination)
def main():
for count, filename in enumerate(os.listdir(Source_Path)):
dst = "Class_2_" + str(count) + ".jpg"
# rename all the files
os.rename(os.path.join(Source_Path, filename), os.path.join(Destination, dst))
# Driver Code
if __name__ == '__main__':
main()
As per #daniel's comment, os.listdir() returns just the filenames and not the full path of the file. Use os.path.join(path, file) to get the full path and rename that.
import os
path = 'C:\\Users\\Admin\\Desktop\\Jayesh'
files = os.listdir(path)
for file in files:
os.rename(os.path.join(path, file), os.path.join(path, 'xyz_' + file + '.csv'))
Just playing with the accepted answer define the path variable and list:
path = "/Your/path/to/folder/"
files = os.listdir(path)
and then loop over that list:
for index, file in enumerate(files):
#print (file)
os.rename(path+file, path +'file_' + str(index)+ '.jpg')
or loop over same way with one line as python list comprehension :
[os.rename(path+file, path +'jog_' + str(index)+ '.jpg') for index, file in enumerate(files)]
I think the first is more readable, in the second the first part of the loop is just the second part of the list comprehension
If your files are renaming in random manner then you have to sort the files in the directory first. The given code first sort then rename the files.
import os
import re
path = 'target_folder_directory'
files = os.listdir(path)
files.sort(key=lambda var:[int(x) if x.isdigit() else x for x in re.findall(r'[^0-9]|[0-9]+', var)])
for i, file in enumerate(files):
os.rename(path + file, path + "{}".format(i)+".jpg")
I wrote a quick and flexible script for renaming files, if you want a working solution without reinventing the wheel.
It renames files in the current directory by passing replacement functions.
Each function specifies a change you want done to all the matching file names. The code will determine the changes that will be done, and displays the differences it would generate using colors, and asks for confirmation to perform the changes.
You can find the source code here, and place it in the folder of which you want to rename files https://gist.github.com/aljgom/81e8e4ca9584b481523271b8725448b8
It works in pycharm, I haven't tested it in other consoles
The interaction will look something like this, after defining a few replacement functions
when it's running the first one, it would show all the differences from the files matching in the directory, and you can confirm to make the replacements or no, like this
This works for me and by increasing the index by 1 we can number the dataset.
import os
path = '/Users/myName/Desktop/directory'
files = os.listdir(path)
index=1
for index, file in enumerate(files):
os.rename(os.path.join(path, file),os.path.join(path,''.join([str(index),'.jpg'])))
index = index+1
But if your current image name start with a number this will not work.