I wrote a script which will scan the shared folders and get the file age of all the files in those folders and some other file meta info.
my_paths = []
for p in ['\\\\data\\hold\\app1','\\\\data\\hold\\app2']:
for dirpath, dirnames, filenames in os.walk(p):
my_paths.append(filenames)
for filename in filenames:
full_path = os.path.join(dirpath, filename)
if last_modified(full_path) < threshold:
string_output='Age :' +age_file(full_path)+'\n'+'File Size : '+file_size(full_path)+'\n'
print(string_output)
#create(string_output);
I have to hard code all the shares in the code, instead I thought of making the script to read from a text file where I can update all the paths.
text.txt
\\data\hold\app1
\\data\hold\app2
revamp code,
my_paths = []
for line in open(r'd:\mydata\text.txt').readlines():
my_paths.append(line.strip())
print my_paths
for dirpath, dirnames, filenames in os.walk(line):
my_paths.append(filenames)
for filename in filenames:
full_path = os.path.join(dirpath, filename)
if last_modified(full_path) < threshold:
string_output='Age :' +age_file(full_path)+'\n'+'File Size : '+file_size(full_path)+'\n'
print(string_output)
#create(string_output);
my_paths returning the data like ['\\data\hold\app1','\\data\hold\app2'] but somehow the rest is not working.
You simply forgot to strip the line you read in the loop:
...
for dirpath, dirnames, filenames in os.walk(line.strip()):
...
Related
I want to get my script to read a list of names from a list(txt), then search for those in a selected folder with subfolders, then copy and paste those files to another selected folder. My script running without error but no result.
My script:
import os
import os.path
import shutil
textFile = ("D:\\Test\\list.txt")
sourceFolder = ("D:\\Test")
destinationFolder = ("D:\\")
filesToFind = []
with open(textFile, "r") as tx:
for row in tx:
filesToFind.append(row.strip())
for root, dirs, filename in os.walk(sourceFolder):
if filename in filesToFind:
f = os.path.join(root, filename)
shutil.copy(f, destinationFolder)
Haven’t test it but I think this will work - change this:
for root, dirs, filename in os.walk(sourceFolder):
if filename in filesToFind:
f = os.path.join(root, filename)
shutil.copy(f, destinationFolder)
To this:
for root, dirs, filenames in os.walk(sourceFolder):
for filename in filenames:
if filename in filesToFind:
f = os.path.join(root, filename)
shutil.copy(f, destinationFolder)
# Same code using glob #
## More efficient and also tested one ##
## One more feature added- checks file name given present or not ##
import os
import os.path
import shutil
import glob
textFile = ("D:\\Test\\list.txt")
sourceFolder = ("D:\Test")
destinationFolder = ("D:\\")
f = open(textFile, "r").readlines()
for i in f:
ListFile= glob.glob(os.path.join(sourceFolder,"**",i.strip()),recursive=True)
if len(ListFile):
print(ListFile[0],destinationFolder,os.path.basename(ListFile[0]))
destinationfile=os.path.join(destinationFolder,os.path.basename(ListFile[0]))
shutil.copyfile(ListFile[0],destinationfile)
else:
print(i,"-File not found")
I have a directory with many subdirectories, containing files. I want to open the files ending with "root.vrpj" or "root.vprj", in "App_integrations" folder and copy the lines containing the word "table" to another file.
Until now I've managed to visit each file with this code:
for root, dirs, files in os.walk(movedir):
for filename in files:
if filename.endswith(("root.vrpj", "root.vprj")):
The problem is that what I have now are just the names of the files I want to visit and I'm stuck here.
You can try this:
f = open('final_file.txt', 'w')
for root, dirs, files in os.walk(movedir):
for filename in files:
if filename.endswith("root.vrpj") or filename.endswith("root.vprj"):
with open(filename) as data:
for line in data:
if "table" in data:
f.write('{}\n'.format(data))
f.close()
This is a version of Ajax' code that closes the files you open in the loop (and fixes a couple of other minor issues):
with open('final_file.txt', 'w') as f:
for root, dirs, files in os.walk(movedir):
for filename in files:
if filename.endswith(("root.vrpj"), ("root.vprj")):
with open(os.path.join(root, filename)) as finput:
for line in finput:
if 'table' in line:
f.write(line)
however, when you see 8 levels of indentation you need to refactor, e.g.:
def find_files(startdir, *extensions):
for root, dirs, files in os.walk(movedir):
for filename in files:
if filename.endswith(extensions):
yield os.path.join(root, filename)
def find_lines(fname, text):
with open(fname) as fp:
return [line for line in fp if text in line]
with open('final_file.txt', 'w') as f:
for fname in find_files(movedir, 'root.vrpj', 'root.vprj'):
f.writelines(find_lines(fname, 'table'))
I finally solved it
import os
rootdir = my root folder
# creates a file f that contains all the lines of the files
# with "root.vrpj" or "root.vprj" in their name
# and who are inside "App_integrations" folders
# without duplicates
#creating the big file with all the file containing the lines I need
f = open('final_file.txt', 'a')
for root, dirs, files in os.walk(rootdir):
for filename in files:
if (filename.endswith(("root.vrpj", "root.vprj")) and ("App_Integration" in os.path.join(root, filename))):
full_name = os.path.join(root, filename)
data = open(full_name).read()
f.write(data + "\n")
f.close()
#copying the lines I need to f1 without duplicates
lines_seen = set()
f = open('final_file.txt')
f1 = open('testread1.txt', 'a')
doIHaveToCopyTheLine=False
for line in f.readlines():
if (("Table" in line) and (line not in lines_seen)):
doIHaveToCopyTheLine=True
if doIHaveToCopyTheLine:
f1.write(line)
lines_seen.add(line)
f1.close()
f.close()
Find the files
from pathlib import Path
import itertools
source_dir = Path(<source_dir>)
patterns = ['**/*root.vrpj', '**/*root.vprj']
files = itertools.chain.from_iterables(source_dir.glob(pat) for pat in patterns))
Filter the files:
def filter_lines(files):
for file in files:
if not 'App_Integration' in file.parts:
continue
with file.open('r') as file_handle:
for line in file_handle:
if 'table' in line:
yield line
Write the output
def save_lines(lines, output_file=sys.std_out):
for line in lines:
output_file.write(line)
with Path(<output_file>).open('w') as output_file:
save_lines(filter_lines(files), as output_file)
I'm trying the get from user a string and place it in the os.walk function.
This is my code:
def FiletypeNumber():
Path=Boaz.get()
Pathw="'"+Path+"'"
print (Pathw)
for (dirpath, dirnames, filenames) in walk(Pathw):
f.extend(filenames)
for i in range(len(f)):
t = f[i]
indexO=t.rindex('.')
LenF=len(t)
Ex=(t[-(LenF-indexO):])
FileTypeList.append(Ex)
if Ex in Typofiles:
pass
else:
Typofiles.append(Ex)
When I print the variable Pathw, I get the wanted results (for example: 'd:\js').
But when I pass this variable to the walk function, my code doesn't work properly.
Its purpose is to:
Enter a directory.
Print the number and type of files in it.
Don't add ' to your path name, such a path does not exist and results in a empty list.
def FiletypeNumber():
path = Boaz.get()
print('{!r}'.format(path))
for (dirpath, dirnames, filenames) in walk(path):
for filename in filenames:
_, ext = os.path.splitext(filename)
FileTypeList.append(ext)
if ext not in Typofiles:
Typofiles.append(ext)
With this code, I am trying to read all files a directory and all its subdirectories. I have another list of files names, if the search finds files in the directories that are on the other list, I want to copy those feature classes to another location. When the code gets to FeatureClasstoGeodatabase, I keep getting an error that the input features data type is not supported or does not exist. I wasn't sure if I needed to somehow get the path as well as the filename so I created a couple of lists to capture that separately, but I'm kind of stuck here:
import arcpy
import os
workspace = r'F:\SF_HMP - transferred to Ydrive'
output_loc = r'C:\temp\temp.gdb'
mssng_files = r'F:\SF_HMP - transferred to Ydrive\Maps\broken_links_missing_files.txt'
files_to_find = []
layers_list = []
layers_path = []
with open(mssng_files) as filelist:
for line in filelist:
files_to_find.append(line.strip())
for dirpath, dirnames, filenames in arcpy.da.Walk(workspace,datatype="FeatureClass"):
for filename in filenames:
layers_list.append(filename)
layers_path.append(os.path.join(dirpath,filename))
for lyr in layers_list:
if lyr in files_to_find:
arcpy.FeatureClassToGeodatabase_conversion(lyr,output_loc)
I realized I needed to specify the workspace for each file to be copied over. I also repeated the code to search for and copy over rasters and tables:
import arcpy,os, easygui,sys
mssng_files = r'L:\SF_HMP - transferred to Ydrive\Maps\broken_links_missing_files.txt'
wkspc = easygui.enterbox("Enter workspace path:",title='Search for Files')
output_loc = easygui.enterbox("Output location:",title='Copy Files')
with open(mssng_files) as filelist:
for line in filelist:
files_to_find.append(line.strip())
for dirpath, dirnames, filenames in arcpy.da.Walk(wkspc,datatype='FeatureClass'):
for filename in filenames:
if filename in files_to_find:
ws_l = os.path.join(dirpath,filename)
arcpy.env.workspace = ws_l
arcpy.FeatureClassToGeodatabase_conversion(ws_l,output_loc)
for dirpath, dirnames, filenames in arcpy.da.Walk(wkspc,datatype='RasterDataset'):
for filename in filenames:
if filename in files_to_find:
ws_r = os.path.join(dirpath,filename)
arcpy.env.workspace = ws_r
arcpy.RasterToGeodatabase_conversion(ws_r,output_loc)
for dirpath, dirnames, filenames in arcpy.da.Walk(wkspc,datatype='Table'):
for filename in filenames:
if filename in files_to_find:
ws_t = os.path.join(dirpath,filename)
arcpy.env.workspace = ws_t
arcpy.TableToGeodatabase_conversion(ws_t,output_loc)
I want to return the path of a file, If it is found by the program, but I want it to continue to loop(or recursively repeat) the program until all files are checked.
def findAll(fname, path):
for item in os.listdir(path):
n = os.path.join(path, item)
try:
findAll(n, fname)
except:
if item == fname:
print(os.idontknow(item))
So I'm having trouble with calling the path, right now I have
os.idontknow(item)
as a place holder
Input is :
findAll('fileA.txt', 'testpath')
The output is:
['testpat\\fileA.txt', 'testpath\\folder1\\folder11\\fileA.txt','testpath\\folder2\\fileA.txt']
Per my comment above, here is an example that will start at the current directory and search through all sub-directories, looking for files matching fname:
import os
# path is your starting point - everything under it will be searched
path = os.getcwd()
fname = 'file1.txt'
my_files = []
# Start iterating, and anytime we see a file that matches fname,
# add to our list
for root, dirs, files in os.walk(path):
for name in files:
if name == fname:
# root here is the path to the file
my_files.append(os.path.join(root, name))
print my_files
Or as a function (more appropriate for your case :) ):
import os
def findAll(fname, start_dir=os.getcwd()):
my_files = []
for root, dirs, files in os.walk(start_dir):
for name in files:
if name == fname:
my_files.append(os.path.join(root, name))
return my_files
print findAll('file1.txt')
print findAll('file1.txt', '/some/other/starting/directory')
Something like this, maybe?
import os
path = "path/to/your/dir"
for (path, dirs, files) in os.walk(path):
print files