I have a package of the following format:
Electricity
|___ __main__.py
|
|__ Electricity
| |___ general_functions
| |___ regression_calcs
| | |___ create_calcs.py
| |
| |____ run_calcs.py
|
|
|
|__ Data_Input
|___ regression_vals
|__ regression_vals.csv
run_calcs.py runs the code in regression_calcs, which requires data from Data_Input/Regression_vals.
What is the most pythonic way to find the number of ../ (number of times to go up a folder), until Data_Input is found?
This is because right now I'm running the scripts in Electricity/Electricity/run_calcs.py (for testing). Eventually I will be running in Electricity/__main__.py.
it will be for df = pd.read_csv(f'{filepath}Data_Input/regression_vals/regression_vals.csv')
where filepath = '../'*n
Inside your files within regression_calcs:
from os import listdir
from os.path import join, isdir, dirname, basename
filepath = None
# get parent of the .py running
par_dir = dirname(__file__)
while True:
# get basenames of all the directories in that parent
dirs = [basename(join(par_dir, d)) for d in listdir(par_dir) if isdir(join(par_dir, d))]
# the parent contains desired directory
if 'Data_Input' in dirs:
filepath = par_dir
break
# back it out another parent otherwise
par_dir = dirname(par_dir)
Of course this only works if you have a single '/Data_Input/' directory!
What I eventually used (a mix between avix & pstatic's answer):
import os, unipath
def rel_location():
"""Goes up until it finds the folder 'Input_Data', then it stops
returns '' or '../' or '../../', or ... depending on how many times it had to go up"""
path = unipath.Path(__file__)
num_tries = 5
for num_up_folder in range(num_tries):
path = path.parent
if 'Input_Data' in os.listdir(path):
break
if num_tries == num_up_folder:
raise FileNotFoundError("The directory 'Input_Data' could not be found in the 5"
" directories above this file's location. ")
location = '../'* num_up_folder
return location
You can use Unipath.
path = Path("/Electricity/Data_Input/regression_vals/regression_vals.csv")
path = path.parent
path = path.parent
And now path refers to /Electricity/Data_Input directory.
Here is an alternate implementation using pathlib and directly returning a Path object for the desired directory.
from pathlib import Path
def get_path_to_rel_location(directory_to_find):
"""Goes up in directory heirarchy until it finds directory that contains
`directory_to_find` and returns Path object of `directory_to_find`"""
path = Path.cwd()
num_tries = 5
for num_up_folder in range(num_tries):
path = path.parent
if path / directory_to_find in path.iterdir():
break
if num_tries == num_up_folder:
raise FileNotFoundError(f"The directory {directory_to_find} could not be found in the {num_tries}"
f" directories above this file's location.")
return path / directory_to_find
# Example usage
path = get_path_to_rel_location("Input_Data")
os.scandir is useful for stuff like this.
def find_my_cousin(me, cousin_name):
"""Find a file or directory named `cousin_name`. Start searching at `me`,
and traverse directly up the file tree until found."""
if not os.path.isdir(me):
parent_folder = os.path.dirname(me)
else:
parent_folder = me
folder = None
removed = -1
while folder != parent_folder: # Stop if we hit the file system root
folder = parent_folder
removed += 1
with os.scandir(folder) as ls:
for f in ls:
if f.name == cousin_name:
print(
"{} is your cousin, {} times removed, and she lives at {}"
"".format(f.name, removed, f.path)
)
return f.path
parent_folder = os.path.normpath(os.path.join(folder, os.pardir))
This answer is a modified version of A H's answer just with Micah Culpepper's exit condition and simplified.
import os
path = os.path.dirname(os.path.abspath(__file__))
while "Input_Data" not in os.listdir(path):
if path == os.path.dirname(path):
raise FileNotFoundError("could not find Input_Data")
path = os.path.dirname(path)
Related
Lets say some paths like these:
C:/Test/path_i_need/test2/test3/test4
C:/Test/test2/path_i_need/test3
C:/Test/test2/test3/path_i_need/test4
How I can extract the path that i need in each of the scenarios using python, for example:
C:/Test/path_i_need
C:/Test/test2/path_i_need
C:/Test/test2/test3/path_i_need
So basically i don't know how many sub folder are before the path_i_need or after it, I only need that path, i dont care whats after.
You could do a DFS (depth-first search) from the root directory until you find all the paths you're looking for:
from os import listdir, path
ROOT_DIR = "./example"
FLAG = "example1"
found_dirs = []
def find_dirs(p):
subdirs = listdir(p)
for subdir in subdirs:
curdir = path.join(p, subdir)
if subdir == FLAG:
found_dirs.append(curdir)
elsif path.isdir(curdir):
find_dirs(curdir)
find_dirs(ROOT_DIR)
Try this, without using os module or any imports:
paths = """
C:/Test/path_i_need/test2/test3/test4
C:/Test/test2/path_i_need/test3
C:/Test/test2/test3/path_i_need/test4
""".strip().split('\n')
need_this_path = 'path_i_need'
len_that_which_i_need = len(need_this_path)
extracted_paths = [p[:p.index(need_this_path) + len_that_which_i_need] for p in paths]
print(*extracted_paths, sep='\n')
Outputs:
C:/Test/path_i_need
C:/Test/test2/path_i_need
C:/Test/test2/test3/path_i_need
I want to navigate from the root directory to all other directories within and print the same.
Here's my code:
#!/usr/bin/python
import os
import fnmatch
for root, dir, files in os.walk("."):
print root
print ""
for items in fnmatch.filter(files, "*"):
print "..." + items
print ""
And here's my O/P:
.
...Python_Notes
...pypy.py
...pypy.py.save
...classdemo.py
....goutputstream-J9ZUXW
...latest.py
...pack.py
...classdemo.pyc
...Python_Notes~
...module-demo.py
...filetype.py
./packagedemo
...classdemo.py
...__init__.pyc
...__init__.py
...classdemo.pyc
Above, . and ./packagedemo are directories.
However, I need to print the O/P in the following manner:
A
---a.txt
---b.txt
---B
------c.out
Above, A and B are directories and the rest are files.
This will give you the desired result
#!/usr/bin/python
import os
# traverse root directory, and list directories as dirs and files as files
for root, dirs, files in os.walk("."):
path = root.split(os.sep)
print((len(path) - 1) * '---', os.path.basename(root))
for file in files:
print(len(path) * '---', file)
try this:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""FileTreeMaker.py: ..."""
__author__ = "legendmohe"
import os
import argparse
import time
class FileTreeMaker(object):
def _recurse(self, parent_path, file_list, prefix, output_buf, level):
if len(file_list) == 0 \
or (self.max_level != -1 and self.max_level <= level):
return
else:
file_list.sort(key=lambda f: os.path.isfile(os.path.join(parent_path, f)))
for idx, sub_path in enumerate(file_list):
if any(exclude_name in sub_path for exclude_name in self.exn):
continue
full_path = os.path.join(parent_path, sub_path)
idc = "┣━"
if idx == len(file_list) - 1:
idc = "┗━"
if os.path.isdir(full_path) and sub_path not in self.exf:
output_buf.append("%s%s[%s]" % (prefix, idc, sub_path))
if len(file_list) > 1 and idx != len(file_list) - 1:
tmp_prefix = prefix + "┃ "
else:
tmp_prefix = prefix + " "
self._recurse(full_path, os.listdir(full_path), tmp_prefix, output_buf, level + 1)
elif os.path.isfile(full_path):
output_buf.append("%s%s%s" % (prefix, idc, sub_path))
def make(self, args):
self.root = args.root
self.exf = args.exclude_folder
self.exn = args.exclude_name
self.max_level = args.max_level
print("root:%s" % self.root)
buf = []
path_parts = self.root.rsplit(os.path.sep, 1)
buf.append("[%s]" % (path_parts[-1],))
self._recurse(self.root, os.listdir(self.root), "", buf, 0)
output_str = "\n".join(buf)
if len(args.output) != 0:
with open(args.output, 'w') as of:
of.write(output_str)
return output_str
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-r", "--root", help="root of file tree", default=".")
parser.add_argument("-o", "--output", help="output file name", default="")
parser.add_argument("-xf", "--exclude_folder", nargs='*', help="exclude folder", default=[])
parser.add_argument("-xn", "--exclude_name", nargs='*', help="exclude name", default=[])
parser.add_argument("-m", "--max_level", help="max level",
type=int, default=-1)
args = parser.parse_args()
print(FileTreeMaker().make(args))
you will get this:
root:.
[.]
┣━[.idea]
┃ ┣━[scopes]
┃ ┃ ┗━scope_settings.xml
┃ ┣━.name
┃ ┣━Demo.iml
┃ ┣━encodings.xml
┃ ┣━misc.xml
┃ ┣━modules.xml
┃ ┣━vcs.xml
┃ ┗━workspace.xml
┣━[test1]
┃ ┗━test1.txt
┣━[test2]
┃ ┣━[test2-2]
┃ ┃ ┗━[test2-3]
┃ ┃ ┣━test2
┃ ┃ ┗━test2-3-1
┃ ┗━test2
┣━folder_tree_maker.py
┗━tree.py
Recursive walk through a directory where you get ALL files from all dirs in the current directory and you get ALL dirs from the current directory - because codes above don't have a simplicity (imho):
for root, dirs, files in os.walk(rootFolderPath):
for filename in files:
doSomethingWithFile(os.path.join(root, filename))
for dirname in dirs:
doSomewthingWithDir(os.path.join(root, dirname))
There are more suitable functions for this in os package. But if you have to use os.walk, here is what I come up with
def walkdir(dirname):
for cur, _dirs, files in os.walk(dirname):
pref = ''
head, tail = os.path.split(cur)
while head:
pref += '---'
head, _tail = os.path.split(head)
print(pref+tail)
for f in files:
print(pref+'---'+f)
output:
>>> walkdir('.')
.
---file3
---file2
---my.py
---file1
---A
------file2
------file1
---B
------file3
------file2
------file4
------file1
---__pycache__
------my.cpython-33.pyc
You could also recursively walk through a folder and lists all it's contents using pathlib.Path()
from pathlib import Path
def check_out_path(target_path, level=0):
""""
This function recursively prints all contents of a pathlib.Path object
"""
def print_indented(folder, level):
print('\t' * level + folder)
print_indented(target_path.name, level)
for file in target_path.iterdir():
if file.is_dir():
check_out_path(file, level+1)
else:
print_indented(file.name, level+1)
my_path = Path(r'C:\example folder')
check_out_path(my_path)
Output:
example folder
folder
textfile3.txt
textfile1.txt
textfile2.txt
You can use os.walk, and that is probably the easiest solution, but here is another idea to explore:
import sys, os
FILES = False
def main():
if len(sys.argv) > 2 and sys.argv[2].upper() == '/F':
global FILES; FILES = True
try:
tree(sys.argv[1])
except:
print('Usage: {} <directory>'.format(os.path.basename(sys.argv[0])))
def tree(path):
path = os.path.abspath(path)
dirs, files = listdir(path)[:2]
print(path)
walk(path, dirs, files)
if not dirs:
print('No subfolders exist')
def walk(root, dirs, files, prefix=''):
if FILES and files:
file_prefix = prefix + ('|' if dirs else ' ') + ' '
for name in files:
print(file_prefix + name)
print(file_prefix)
dir_prefix, walk_prefix = prefix + '+---', prefix + '| '
for pos, neg, name in enumerate2(dirs):
if neg == -1:
dir_prefix, walk_prefix = prefix + '\\---', prefix + ' '
print(dir_prefix + name)
path = os.path.join(root, name)
try:
dirs, files = listdir(path)[:2]
except:
pass
else:
walk(path, dirs, files, walk_prefix)
def listdir(path):
dirs, files, links = [], [], []
for name in os.listdir(path):
path_name = os.path.join(path, name)
if os.path.isdir(path_name):
dirs.append(name)
elif os.path.isfile(path_name):
files.append(name)
elif os.path.islink(path_name):
links.append(name)
return dirs, files, links
def enumerate2(sequence):
length = len(sequence)
for count, value in enumerate(sequence):
yield count, count - length, value
if __name__ == '__main__':
main()
You might recognize the following documentation from the TREE command in the Windows terminal:
Graphically displays the folder structure of a drive or path.
TREE [drive:][path] [/F] [/A]
/F Display the names of the files in each folder.
/A Use ASCII instead of extended characters.
This does it for folder names:
def printFolderName(init_indent, rootFolder):
fname = rootFolder.split(os.sep)[-1]
root_levels = rootFolder.count(os.sep)
# os.walk treats dirs breadth-first, but files depth-first (go figure)
for root, dirs, files in os.walk(rootFolder):
# print the directories below the root
levels = root.count(os.sep) - root_levels
indent = ' '*(levels*2)
print init_indent + indent + root.split(os.sep)[-1]
#!/usr/bin/python
import os
def tracing(a):
global i>
for item in os.listdir(a):
if os.path.isfile(item):
print i + item
else:
print i + item
i+=i
tracing(item)
i = "---"
tracing(".")
Would be the best way
import os
def traverse_dir_recur(directory):
l = os.listdir(directory)
for d in l:
if os.path.isdir(directory + d):
traverse_dir_recur(directory + d +"/")
else:
print(directory + d)
Given a folder name, walk through its entire hierarchy recursively.
#! /usr/local/bin/python3
# findLargeFiles.py - given a folder name, walk through its entire hierarchy
# - print folders and files within each folder
import os
def recursive_walk(folder):
for folderName, subfolders, filenames in os.walk(folder):
if subfolders:
for subfolder in subfolders:
recursive_walk(subfolder)
print('\nFolder: ' + folderName + '\n')
for filename in filenames:
print(filename + '\n')
recursive_walk('/name/of/folder')
Try this:
import os
root_name = next(os.walk("."))[0]
dir_names = next(os.walk("."))[1]
file_names = next(os.walk("."))[2]
Here I'm assuming your path as "." in which the root_file and other directories are there.
So, Basically we are just iterating throughout the tree by using next() call, as our os.walk is only generative function.
By doing this we can save all the Directory and file names in dir_names and file_names respectively.
Do try this; easy one
#!/usr/bin/python
import os
# Creating an empty list that will contain the already traversed paths
donePaths = []
def direct(path):
for paths,dirs,files in os.walk(path):
if paths not in donePaths:
count = paths.count('/')
if files:
for ele1 in files:
print '---------' * (count), ele1
if dirs:
for ele2 in dirs:
print '---------' * (count), ele2
absPath = os.path.join(paths,ele2)
# recursively calling the direct function on each directory
direct(absPath)
# adding the paths to the list that got traversed
donePaths.append(absPath)
path = raw_input("Enter any path to get the following Dir Tree ...\n")
direct(path)
========OUTPUT below========
/home/test
------------------ b.txt
------------------ a.txt
------------------ a
--------------------------- a1.txt
------------------ b
--------------------------- b1.txt
--------------------------- b2.txt
--------------------------- cde
------------------------------------ cde.txt
------------------------------------ cdeDir
--------------------------------------------- cdeDir.txt
------------------ c
--------------------------- c.txt
--------------------------- c1
------------------------------------ c1.txt
------------------------------------ c2.txt
Let's say you have an arbitrary parent directory with subdirectories as such:
/home/parent_dir
├── 0_N
├── 1_M
├── 2_P
├── 3_R
└── 4_T
And here is what you can do to estimate the approximate percent distribution #files in each subdirectory relative to the total #files in parent:
from os import listdir as osl
from os import walk as osw
from os.path import join as osj
def subdir_summary(parent_dir):
parent_dir_len = sum([len(files) for _, _, files in osw(parent_dir)])
print(f"Total files in parent: {parent_dir_len}")
for subdir in sorted(osl(parent_dir)):
subdir_files_len = len(osl(osj(parent_dir, subdir)))
print(subdir, subdir_files_len, f"{int(100*(subdir_files_len / parent_dir_len))}%")
subdir_summary("/home/parent_dir")
It will print in terminal as follows:
Total files in parent: 5876
0_N 3254 55%
1_M 509 8%
2_P 1187 20%
3_R 594 10%
4_T 332 5%
import os
os.chdir('/your/working/path/')
dir = os.getcwd()
list = sorted(os.listdir(dir))
marks = ""
for s_list in list:
print marks + s_list
marks += "---"
tree_list = sorted(os.listdir(dir + "/" + s_list))
for i in tree_list:
print marks + i
I wrote a MoviePy script that takes an input video, does some processing, and outputs a video file. I want to run this through an entire folder of videos. Any help or direction is appreciated.
Here's what I tried...
for f in *; do python resize.py $f; done
and resize.py source code here:
from moviepy.editor import *
clip = VideoFileClip(input)
clip1 = clip.rotate(270)
clip2 = clip1.crop(x_center=540,y_center=960,width=1080,height=608)
clip3 = clip2.resize(width=1920)
clip3.write_videofile(output,codec='libx264')
Really wasn't sure what to put for "input" and "output" in my .py file.
Thanks,
Evan
I know you have an answer on Github, but I'll add my own solution.
First, you'll want to put your code inside a function:
def process_video(input):
"""Parameter input should be a string with the full path for a video"""
clip = VideoFileClip(input, output)
clip1 = clip.rotate(270)
clip2 = clip1.crop(x_center=540,y_center=960,width=1080,height=608)
clip3 = clip2.resize(width=1920)
clip3.write_videofile(output,codec='libx264')
Then, you can have a function that returns a list of file paths, and a list of final file names to use with the above function (note that the final file names will be the same as the original file names but with "output" in front):
import os
def get_video_paths(folder_path):
"""
Parameter folder_path should look like "Users/documents/folder1/"
Returns a list of complete paths
"""
file_name_list = os.listdir(folder_path)
path_name_list = []
final_name_list = []
for name in file_name_list:
# Put any sanity checks here, e.g.:
if name == ".DS_Store":
pass
else:
path_name_list.append(folder_path + name)
# Change the format of the output file names below
final_name_list.append(folder_path + "output" + name)
return path_name_list, final_name_list
Finally, at the bottom, we get the input folder, and utilise the above two functions:
if __name__ == "__main__":
video_folder = input("What folder would you like to process? ")
path_list, final_name_list = get_video_paths(video_folder)
for path, name in zip(path_list, final_name_list):
process_video(path, name)
print("Finished")
Just watch out, because this will crash if there are any files in the folder that can't be read as a movie. For instance, on mac, the OS puts a ".DS_Store" file in each folder, which will crash the program. I've put an area for a sanity check to ignore certain filenames.
Complete code:
import os
from moviepy.editor import *
def process_video(input, output):
"""Parameter input should be a string with the full path for a video"""
clip = VideoFileClip(input)
clip1 = clip.rotate(270)
clip2 = clip1.crop(x_center=540,y_center=960,width=1080,height=608)
clip3 = clip2.resize(width=1920)
clip3.write_videofile(output,codec='libx264')
def get_video_paths(folder_path):
"""
Parameter folder_path should look like "Users/documents/folder1/"
Returns a list of complete paths
"""
file_name_list = os.listdir(folder_path)
path_name_list = []
final_name_list = []
for name in file_name_list:
# Put any sanity checks here, e.g.:
if name == ".DS_Store":
pass
else:
path_name_list.append(folder_path + name)
final_name_list.append(folder_path + "output" + name)
return path_name_list, final_name_list
if __name__ == "__main__":
video_folder = input("What folder would you like to process? ")
path_list, final_name_list = get_video_paths(video_folder)
for path, name in zip(path_list, final_name_list):
process_video(path, name)
print("Finished")
I responded on your Github issue #542, but I copied it here for future reference!
First off, the below example isn't ironclad, but it should do what you need.
You can achieve this via something like this:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Convert all media assets located in a specified directory."""
import glob
import os
from optparse import OptionParser
from moviepy.editor import VideoFileClip
def get_dir_files(dir_path, patterns=None):
"""Get all absolute paths for pattern matched files in a directory.
Args:
dir_path (str): The path to of the directory containing media assets.
patterns (list of str): The list of patterns/file extensions to match.
Returns:
(list of str): A list of all pattern-matched files in a directory.
"""
if not patterns or type(patterns) != list:
print('No patterns list passed to get_dir_files, defaulting to patterns.')
patterns = ['*.mp4', '*.avi', '*.mov', '*.flv']
files = []
for pattern in patterns:
dir_path = os.path.abspath(dir_path) + '/' + pattern
files.extend(glob.glob(dir_path))
return files
def modify_clip(path, output):
"""Handle conversion of a video file.
Args:
path (str): The path to the directory of video files to be converted.
output (str): The filename to associate with the converted file.
"""
clip = VideoFileClip(path)
clip = clip.rotate(270)
clip = clip.crop(x_center=540, y_center=960, width=1080, height=608)
clip = clip.resize(width=1920)
clip.write_videofile(output, codec='libx264')
print('File: {} should have been created.'.format(output))
if __name__ == '__main__':
status = 'Failed!'
parser = OptionParser(version='%prog 1.0.0')
parser.add_option('-p', '--path', action='store', dest='dir_path',
default='.', type='string',
help='the path of the directory of assets, defaults to .')
options, args = parser.parse_args()
print('Running against directory path: {}'.format(options.dir_path))
path_correct = raw_input('Is that correct?').lower()
if path_correct.startswith('y'):
dir_paths = get_dir_files(options.dir_path)
for dir_path in dir_paths:
output_filename = 'converted_' + os.path.basename(dir_path)
modify_clip(path=dir_path, output=output_filename)
status = 'Successful!'
print('Conversion {}'.format(status))
With the above example, you can simply drop that into the directory of assets you wish to convert and run: python this_file.py and it should convert the files for you in the same directory with the name prepended with: converted_
Likewise, you can drop that file anywhere and run it against an absolute path:
python this_file.py -p /Users/thisguy/media and it will convert all files with the extensions: ['*.mp4', '*.avi', '*.mov', '*.flv']
Either way, let me know if you have any questions (or if this resolves your issue) and I'll do my best to help you out!
Thanks for using moviepy!
Hi After 2 hours of googling and searching I am failing to find, or build a simple piece of code for the following setup:
3 folders, 2 files:
/home/folderA/text2.txt
/home/folderB/
/home/folderB/folder1
/home/folderB/text1.txt
Moving the "Unknown" content of folderB to folderA.
All the attempts at solving this issue are either deemed too trivial and redirected to "look up shutil." or yielding half a page of code for a specific setup with different demands, rendering it impossible for my miserable pythonskills to develop a sufficient (elegant) result.
In python I have a procedure to identify the existence of folderB, but its contents are unknown and varying to me. In light of full disclosure; here is my XYproblem:
#!/usr/bin/python
from glob import glob
path1 =glob('*')
path2 = glob('*/*/')
print path1
print path2
print len(path2)
a = len(path2)
for i in range(0,a):
print len(path2[i]), path2[i], path2[i][len(path2[i])-2]
print(path2[i][len(path2[i])-2].isdigit())
if path2[i][len(path2[i])-3]==" " and path2[i][len(path2[i])-2].isdigit():
print('yay')
newpath =path2[i][:len(path2[i])-2]+"0"+path2[i][(len(path2[i])-2):]
print(newpath)
import os
print(os.path.isdir(newpath))
if os.path.isdir(newpath): #if it is true, the new folder with the " 0n" already exists
import shutil
newpath0=path2[i]+ '*/'
print(newpath0, "headsup", newpath)
shutil.copy(newpath0,newpath)
#shutil.move(
But for the sake of those who seek an efficient, simple solution to this problem please keep it to the simplified, and hypothetical case of "folderX" :)
-edit-
Because the folderA indeed already exists, and has the same (potential) hierarchy as folderB. That is why
shutil.rmtree('folderA')
is not an option; folderA should remain intact.
So, ironically, temporarily removing the contents of folderA to put the contents of folderB in it, yields essentially the exact same problem as I am trying to solve.
-edit2-
Thanks for the effort, I keep on getting:
SyntaxError: invalid syntax
at the
def mv(from_folder, to_folder)
^
Now I appologize for my exceptional level of retardedness but I currently lack the clarity to comprehend how you envisioned your solution;
So after looking up the def mv(.. function I came to the conclusion that you might mean that from_folder should be replaced by a string which contains folderB.
So I tried 2 options:
your original
defining:
stringA='folderA', stringB=folderB
and substituting from_folder with stringB and to_folder with stringA in the first 3 rows of your code.
Both yield the same error.
*Note import os and import shutil have already been performed within the active if loop. Just to ensure that was the not causing the problem, I also tried it with an the given explicit import os and import shutil immediatly above def..
the code I so far have hence looks like:
#!/usr/bin/python
from glob import glob
path1 =glob('*')
path2 = glob('*/*/')
#print path1
#print path2
#print len(path2)
a = len(path2)
for i in range(0,a):
#print len(path2[i]), path2[i], path2[i][len(path2[i])-2]
#print(path2[i][len(path2[i])-2].isdigit())
if path2[i][len(path2[i])-3]==" " and path2[i][len(path2[i])-2].isdigit():
#print('yay')
newpath =path2[i][:len(path2[i])-2]+"0"+path2[i][(len(path2[i])-2):]
#print(newpath)
import os
#print(os.path.isdir(newpath))
if os.path.isdir(newpath): #if it is true, the new folder with the " 0n" already exists
import shutil
newpath0=path2[i]+ '*/'
#print(newpath0, "hier", newpath, ' en path2[i] ', path2[i])
#shutil.copy(newpath0,newpath)
#from here chose from_folder = path2[i] and to_folder=newpath
stringb = path2[i]
stringa = newpath
print(stringb,' ', stringa)
print('reached')
def mv(stringb, stringa):
root_src_dir = stringb
print('reached')
root_dst_dir = stringa
for src_dir, dirs, files in os.walk(root_src_dir):
dst_dir = src_dir.replace(root_src_dir, root_dst_dir)
if not os.path.exists(dst_dir):
os.mkdir(dst_dir)
for file_ in files:
src_file = os.path.join(src_dir, file_)
dst_file = os.path.join(dst_dir, file_)
if os.path.exists(dst_file):
os.remove(dst_file)
shutil.move(src_file, dst_dir)
But it refuses to print the second "reached", or in other words, it does not define
import shutil
shutil.copytree('folderB', 'folderA')
Just make sure folderA doesn't exist before running the command.
If for some reason the folder already exists beforehand and you have no control over that, just do
shutil.rmtree('folderA')
shutil.copytree('folderB', 'folderA')
Thanks for all the help! I've tried a different approach;
#!/usr/bin/python
from glob import glob
path1 =glob('*')
path2 = glob('*/*/')
print path1
print('hi')
#print path2
#print len(path2)
a = len(path2)
for i in range(0,a):
#print len(path2[i]), path2[i], path2[i][len(path2[i])-2]
#print(path2[i][len(path2[i])-2].isdigit())
if path2[i][len(path2[i])-3]==" " and path2[i][len(path2[i])-2].isdigit():
#print('yay')
newpath =path2[i][:len(path2[i])-2]+"0"+path2[i][(len(path2[i])-2):]
#print(newpath)
import os
#print(os.path.isdir(newpath))
if os.path.isdir(newpath): #if it is true, the new folder with the " 0n" already exists
import shutil
newpath0=path2[i]+ '*/'
#print(newpath0, "hi", newpath, ' en path2[i] ', path2[i])
#shutil.copy(newpath0,newpath)
#from here chose from_folder = path2[i] and to_folder=newpath
#stringb = path2[i]
#stringa = newpath
#print(stringb,' ', stringa)
print('reached')
subb = os.listdir(path2[i]) #subb is defined here as a list of all the subfolders and subfiles in folderB
#print(subb,len(subb))
print(newpath) #newpath = folderA
for c in range(0,(len(subb))): #This creates an index running for running through all the entries in subb
completesubb=range(len(subb)) #This line defines an array which will contain the full path to all the subfolders and subfiles within folderB
completesubb[c] = path2[i]+subb[c]#here the full path to the subfolders and subfiles within folderB is created,(with 1 sub-file/folder per entry in the array)
print completesubb[c]
completesuba=range(len(subb)) #This will not be required
#move_file(completesubb[c],newpath) #gave an error
shutil.move(completesubb[c],newpath) #moves everythin inside folderB to inside folderA
Now all that is left for me to do is improve the recognizing procedure for "folderA" and folderB but that's another story :) Thnx everyone, as soon as my rep reaches 15 you'll get an automated raise ;)
Try this
import os
import shutil
def mv(from_folder, to_folder):
root_src_dir = from_folder
root_dst_dir = to_folder
for src_dir, dirs, files in os.walk(root_src_dir):
dst_dir = src_dir.replace(root_src_dir, root_dst_dir)
if not os.path.exists(dst_dir):
os.mkdir(dst_dir)
for file_ in files:
src_file = os.path.join(src_dir, file_)
dst_file = os.path.join(dst_dir, file_)
if os.path.exists(dst_file):
os.remove(dst_file)
shutil.move(src_file, dst_dir)
Then
>>>mv('path/to/folderB', 'path/to/folderA')
The code I have now:
import os
Tree = {}
Tree = os.listdir('Dir')
>>> print(Tree)
['New Folder', 'Textfile1.txt', 'Textfile2.txt']
That doesn't print out the files in the subdirectories. (New Folder is a subdirectory).
My question is, how can I output all the files in the directory and the files in subdirectories?
import os
def Test1(rootDir):
list_dirs = os.walk(rootDir)
for root, dirs, files in list_dirs:
for d in dirs:
print os.path.join(root, d)
for f in files:
print os.path.join(root, f)
OR:
import os
def Test2(rootDir):
for lists in os.listdir(rootDir):
path = os.path.join(rootDir, lists)
print path
if os.path.isdir(path):
Test2(path)
For the test file tree:
E:\TEST
│--A
│ │--A-A
│ │ │--A-A-A.txt
│ │--A-B.txt
│ │--A-C
│ │ │--A-B-A.txt
│ │--A-D.txt
│--B.txt
│--C
│ │--C-A.txt
│ │--C-B.txt
│--D.txt
│--E
Running the following code:
Test1('E:\TEST')
print '======================================='
Test2('E:\TEST')
You can see there are difference between the results:
>>>
E:\TEST\A
E:\TEST\C
E:\TEST\E
E:\TEST\B.txt
E:\TEST\D.txt
E:\TEST\A\A-A
E:\TEST\A\A-C
E:\TEST\A\A-B.txt
E:\TEST\A\A-D.txt
E:\TEST\A\A-A\A-A-A.txt
E:\TEST\A\A-C\A-B-A.txt
E:\TEST\C\C-A.txt
E:\TEST\C\C-B.txt
=======================================
E:\TEST\A
E:\TEST\A\A-A
E:\TEST\A\A-A\A-A-A.txt
E:\TEST\A\A-B.txt
E:\TEST\A\A-C
E:\TEST\A\A-C\A-B-A.txt
E:\TEST\A\A-D.txt
E:\TEST\B.txt
E:\TEST\C
E:\TEST\C\C-A.txt
E:\TEST\C\C-B.txt
E:\TEST\D.txt
E:\TEST\E
>>>
To save them in a list:
import os
files = []
def Test1(rootDir):
files.append(rootDir)
list_dirs = os.walk(rootDir)
for root, dirs, files in list_dirs:
for d in dirs:
files.append(os.path.join(root, d))
for f in files:
files.append(os.path.join(root, f))
import os
files = [rootDir]
def Test2(rootDir):
for lists in os.listdir(rootDir):
path = os.path.join(rootDir, lists)
files.append(path)
if os.path.isdir(path):
Test2(path)
From recipe 577091 on the Python Cookbook, you might use or learn from the TREE Emulator there.
import sys, os
FILES = False
def main():
if len(sys.argv) > 2 and sys.argv[2].upper() == '/F':
global FILES; FILES = True
try:
tree(sys.argv[1])
except:
print('Usage: {} <directory>'.format(os.path.basename(sys.argv[0])))
def tree(path):
path = os.path.abspath(path)
dirs, files = listdir(path)[:2]
print(path)
walk(path, dirs, files)
if not dirs:
print('No subfolders exist')
def walk(root, dirs, files, prefix=''):
if FILES and files:
file_prefix = prefix + ('|' if dirs else ' ') + ' '
for name in files:
print(file_prefix + name)
print(file_prefix)
dir_prefix, walk_prefix = prefix + '+---', prefix + '| '
for pos, neg, name in enumerate2(dirs):
if neg == -1:
dir_prefix, walk_prefix = prefix + '\\---', prefix + ' '
print(dir_prefix + name)
path = os.path.join(root, name)
try:
dirs, files = listdir(path)[:2]
except:
pass
else:
walk(path, dirs, files, walk_prefix)
def listdir(path):
dirs, files, links = [], [], []
for name in os.listdir(path):
path_name = os.path.join(path, name)
if os.path.isdir(path_name):
dirs.append(name)
elif os.path.isfile(path_name):
files.append(name)
elif os.path.islink(path_name):
links.append(name)
return dirs, files, links
def enumerate2(sequence):
length = len(sequence)
for count, value in enumerate(sequence):
yield count, count - length, value
if __name__ == '__main__':
main()
Here is yet another version appropriate for python3
Example output:
pyvarstar/
|-- .bashrc
|-- README
|-- vstars -> versions/vstars_20170804/
|-- versions/
| |-- vstars_20170804/
| | |-- lib/
| | | |-- vstars/
| | |-- bin/
| | | |-- getcoords
| | | |-- find_burst
The code:
def realname(path, root=None):
if root is not None:
path=os.path.join(root, path)
result=os.path.basename(path)
if os.path.islink(path):
realpath=os.readlink(path)
result= '%s -> %s' % (os.path.basename(path), realpath)
return result
def ptree(startpath, depth=-1):
prefix=0
if startpath != '/':
if startpath.endswith('/'): startpath=startpath[:-1]
prefix=len(startpath)
for root, dirs, files in os.walk(startpath):
level = root[prefix:].count(os.sep)
if depth >-1 and level > depth: continue
indent=subindent =''
if level > 0:
indent = '| ' * (level-1) + '|-- '
subindent = '| ' * (level) + '|-- '
print('{}{}/'.format(indent, realname(root)))
# print dir only if symbolic link; otherwise, will be printed as root
for d in dirs:
if os.path.islink(os.path.join(root, d)):
print('{}{}'.format(subindent, realname(d, root=root)))
for f in files:
print('{}{}'.format(subindent, realname(f, root=root)))
Use os.walk:
>>> import os
>>> print(os.walk.__doc__)
Directory tree generator.
For each directory in the directory tree rooted at top (including top
itself, but excluding '.' and '..'), yields a 3-tuple
...
If you want to limit your printed tree to some given depth, probably because you have a lot of nested folders, then you don't want to use os.walk. Instead you want to stop iterating through the nested folders as soon as you've reached your desired depth.
from typing import Union, Optional
from pathlib import Path
def ptree(startpath: Union[str, Path],
max_depth:int = 1,
quick_glance: Optional[int] = None,
_current_depth:int = 0) -> None:
"""
Recursively print directory tree up to a given `max_depth`, specifying if you
like a limited number of files and dirs to include in a `quick_glance`.
Parameters
----------
startpath: Union[str, Path]
The filepath at which to start.
max_depth: int
The maximum depth of nested directories to explore.
quick_glance: Optional[int]
If specified, limits exploration to the first however-many files and dirs.
_current_depth: int
So that we can track our depth as we call the function recursively.
"""
if _current_depth==0:
print(startpath)
else:
print(f'{"--"*_current_depth}{[d for d in startpath.split(os.sep) if d][-1]}')
_current_depth += 1
if _current_depth > max_depth:
return None
else:
ls = os.listdir(startpath)
files = [f for f in ls if os.path.isfile(os.path.join(startpath,f))]
dirs = [d for d in ls if os.path.isdir(os.path.join(startpath,d))]
if quick_glance:
files = files[:quick_glance]
dirs = dirs[:quick_glance]
[print(f'{".."*_current_depth}{f}') for f in files]
[ptree(os.path.join(startpath, d), max_depth, quick_glance, _current_depth)
for d in dirs]
return None