How to get listdir of a path with it path - python

i want this
>>> from os import listdir
>>> listdir(g:/new folder)
[g:/new folder/file 1, g:/new folder/file 2\]
but i'm getting this
>>> from os import listdir
>>> listdir(g:/new folder)
[file 1, file 2\]

Use os.scandir function to get full path for each entry:
import os
for f in os.scandir('your_path'):
print(f.path)

import os
directory = "g:/new folder"
files = os.listdir(directory)
files_with_path = [directory+"/"+filename for filename in files]
It should do the trick given the doc, you could also look at the glob package
https://docs.python.org/3/library/os.html#os.listdir
https://docs.python.org/3/library/glob.html

Related

How can i change file name while copying them using shutil?

I am using shutil to copy my files to another destination directory , what i want to achieve is
src/red.png
src/blue.png
src/green.png
for example if i select blue and green then while saving i want them to be saved as
dst/blue_1001.png
dst/green_1002.png
Thanks
Kartikey
All you need to do is to construct a destination path in a format that you want and shutil will do rest of the job.
I am using pathlib module here because it provides convenient APIs to work with paths.
>>> import shutil
>>> from pathlib import Path
>>>
>>> files_to_copy = ["src/red.png", "src/blue.png"]
>>>
>>> destination = Path("dst")
>>>
>>> for index, file in enumerate(map(Path, files_to_copy), start=1001):
... destination_filename = f"{file.stem}_{index}{file.suffix}"
... print(f"{destination_filename=}")
... _ = shutil.copy(file, destination / destination_filename)
...
destination_filename='red_1001.png'
destination_filename='blue_1002.png'
Shutils supports setting the name of the target file. It mainly depends on how you splice the name of the target file
import shutil
from pathlib import Path
parent_path = Path(__file__).parent
file_path = parent_path.joinpath("test2.py")
shutil.copy(file_path, parent_path.joinpath("test3.py"))

How to move files with similar filename into new folder in Python

I have a list of files like this in the images folder.
and How can I create a new folder if there are multiple files with a similar name and move those similar files to that folder?
I am new to python.
Here is my expectation:
Try this:
import glob
from pathlib import Path
for fn in Path("Images").glob("*"):
file_base_name = "_".join(fn.stem.split("_")[:-1])
file_count = len(glob.glob1("Images", f"{file_base_name}*"))
if file_count > 1 or Path(file_base_name).is_dir():
outdir = Path("Images") / file_base_name
outdir.mkdir(exist_ok=True)
fn.rename(outdir / fn.name)
Input:
Output:
Please ignore file names extension. I create those just to test my code
In this case you don't even need re:
from pathlib import Path
for fn in Path("Images").glob("*.jpg"):
outdir = Path("Images") / "_".join(fn.stem.split("_")[:-1])
outdir.mkdir(exist_ok=True)
fn.rename(outdir / fn.name)
What's going on here?
Pathlib is how you want to think of paths if you can. It combines most of the os.path apis. Specifically:
glob gets us all the files matching the glob in the path
mkdir makes the directory (only if it doesn't exist)
rename moves the file there
I am unable to test since I don't have your files. My suggestion would be to comment out the mkdir command and the shutil.move command and replace them with print statements to see what commands would be generated before letting it run for real. But I think it should work.
import pathlib
import os
import re
from itertools import groupby
import shutil
source_dir = 'Images'
files = [os.path.basename(f) for f in pathlib.Path(source_dir).glob('*.jpg')]
def keyfunc(file):
m = re.match('^(.*?)_\d+.jpg$', file)
return m[1]
matched_files = [file for file in files if re.search(r'_\d+.jpg$', file)]
matched_files.sort()
for k, g in groupby(matched_files, keyfunc):
new_dir = os.path.join(source_dir, k)
if not os.path.exists(new_dir):
os.mkdir(new_dir)
for file in g:
shutil.move(os.path.join(source_dir, file), new_dir)

pathlib prints the current directory path

import os
import sys
import pathlib
for folderName,subfolders,filenames in os.walk('/'):
for filename in filenames:
# print(filename)
if filename.endswith('.pdf'):
path=pathlib.Path(filename).parent.absolute()
print("the file "+str(filename)+" has path "+str(path))
I want this script to look for all the pdf files in the os and i also want to print the path of the file but when i run the script it print the file names but prints the path in which i have the python script and not print the path to the pdf file.
This should work:
import os
import sys
import pathlib
for folderName,subfolders,filenames in os.walk('/'):
for filename in filenames:
if filename.endswith('.pdf'):
print(f"the file {filename} has path {folderName}")
You don't need pathlib for this one.
pathlib.Path(filename) will consider filename as a relative path, and thus its parent will be the folder from which the script was runned.

ZipFile bad directory structure

I try make some scripts which helps me zip a file from selected dir.
I have:
import sys
import os
import zipfile
source_dir = "C:\\myDir\\yourDir\\"
zip = zipfile.ZipFile("C:\\myDir\\yourDirZip.zip","w",allowZip64=True)
for root, dirs, files in os.walk(source_dir):
for f in files:
zip.write(os.path.join(root,f))
zip.close()
After execution, in yourDirZip.zip is:
myDir/
yourDir/
...
I expect directly only yourDir or even only content of yourDir
Have you any ideas on how I can get what I want?
You can specify arcname parameter in the write method:
import sys
import os
import zipfile
source_dir = "C:\\myDir\\yourDir"
zip = zipfile.ZipFile("C:\\myDir\\yourDirZip.zip","w",allowZip64=True)
for root, dirs, files in os.walk(source_dir):
for f in files:
zip.write(os.path.join(root,f), arcname=f)
zip.close()

Search files in folder using part of the name and save/copy to different folder using Python

I have 700 files in a single folder. I need to find files that have "h10v03" as part of the name and copy them to a different folder using python.
Heres an example of one of the files: MOD10A1.A2000121.h10v03.005.2007172062725.hdf
I appreciate any help.
Something like this would do the trick.
import os
import shutil
source_dir = "/some/directory/path"
target_dir = "/some/other/directory/path"
part = "h10v03"
files = [file for file in os.listdir(source_dir)
if os.path.isfile(file) and part in file]
for file in files:
shutil.copy2(os.path.join(source_dir, file), target_dir)
Does it need to be python?
A unix shell does that for you quite fine:
cp ./*h10v03* /other/directory/
In python I would suggest you take a look at os.listdir() and shutil.copy()
EDIT:
some untested code:
import os
import shutil
src_dir = "/some/path/"
target_dir = "/some/other/path/"
searchstring = "h10v03"
for f in os.listdir(src_dir):
if searchstring in f and os.path.isfile(os.path.join(src_dir, f)):
shutil.copy2(os.path.join(src_dir, f), target_dir)
print "COPY", f
with the glob module (untested):
import glob
import os
import shutil
for f in glob.glob("/some/path/*2000*h10v03*"):
print f
shutil.copy2(f, os.path.join("/some/target/dir/", os.path.basename(f)))
Firstly, find all the items in that folder with os.listdir. Then you can use the count() method of string to determine if it has your string. Then you can use shutil to copy the file.

Categories