I am making a program in python where I read a filepath, put different pieces of that path in variables, change the path and make a new dir with that path. Everything almost seems to work. But at the end when I try to create the new dirs I am getting 'unexpected indent' error on
newFilePath.mkdir(parents=True)
I can't seem to find the problem.
import os
import shutil
from pathlib import Path
root = "C:\Voorleessoftware\\"
path = os.path.join(root, "targetdirectory")
for path, subdirs, files in os.walk(root):
for name in files:
filePath = str(os.path.join(path, name))
#filepath voorbeeld = c:\Voorleessoftware\1 sept\10u30\1e graad\1A1\test.txt
findchar1 = '\\'
list = [pos for pos, char in enumerate(filePath) if char == findchar1]
rootDir = filePath[0:list[0]]
standaard = filePath[list[0]:list[1]]
dag = filePath[list[1]:list[2]]
uur = filePath[list[2]:list[3]]
graad = filePath[list[3]:list[4]]
klas = filePath[list[4]:list[5]]
bestand = filePath[list[5]:len(filePath)-1]
#nieuwe filepath
newFilePath = rootDir + standaard + dag + graad + klas + uur + bestand
# Dirs aanmaken nieuw filepath
newFilePath.mkdir(parents=True)
Thanks in advance
You have no indentation between
newFilePath = rootDir + standaard + dag + graad + klas + uur + bestand
and
# Dirs aanmaken nieuw filepath
newFilePath.mkdir(parents=True)
Which means your two for blocks are interpreted as ending after the former, which in turn means that your indentations for the last line are unexpected. To see the difference, try marking (with your cursor) the empty line before the #nieuwe filepath, and then also the empty line before the # Dirs aanmaken nieuw filepath – you'll see the difference.
it should be either this
root = "C:\Voorleessoftware\"
or this root = "C:\\Voorleessoftware\\"
always use \\ to represent path in windows
thank you
Related
I have this error when I'm trying to run this code, maybe anyone can help me and give me directions.
After that problem will be solved, I need to create a loop that searching in all the xml files and finding a string, if that sting is in the file than it will move the file to the directory, anyone have an idea how can I do it?
import os
import glob
import shutil
def remove_ext(list_of_pathnames):
"""
removes the extension from each filename
"""
return [os.path.splitext(filename)[0] for filename in list_of_pathnames]
path = os.getcwd()
os.chdir("D:\\TomProject\\Images\\")
os.mkdir("Done\\") # create a new folder
newpath = os.path.join("D:\\TomProject\\","image_with_xml") # made it os independent...
list_of_jpgs = glob.glob(path+"*.jpg")
list_of_xmls = glob.glob(path+"*.xml")
list_of_txts = glob.glob(path+"*.txt")
print(list_of_jpgs, "\n\n", list_of_xmls, "\n\n", list_of_txts) #remove
jpgs_without_extension = remove_ext(list_of_jpgs)
xmls_without_extension = remove_ext(list_of_xmls)
txts_without_extension = remove_ext(list_of_txts)
for filename in jpgs_without_extension:
if filename in xmls_without_extension:
if filename in txts_without_extension:
print("moving", filename) #remove
shutil.move(filename + '*.jpg', newpath) # move image to new path.
shutil.move(filename + '*.xml', newpath)
shutil.move(filename + '*.txt', newpath)
make sure all jpg, xml, txt are in the current working directory. you may add one line to check current directory with
print(path)
please change the lines
list_of_jpgs = glob.glob(path+"*.jpg")
list_of_xmls = glob.glob(path+"*.xml")
list_of_txts = glob.glob(path+"*.txt")
to
list_of_jpgs = glob.glob(os.path.join(path,"*.jpg"))
list_of_xmls = glob.glob(os.path.join(path,"*.xml"))
list_of_txts = glob.glob(os.path.join(path,"*.txt"))
last three lines should be indented. and * should be removed.
for filename in jpgs_without_extension:
if filename in xmls_without_extension:
if filename in txts_without_extension:
print("moving", filename) #remove
shutil.move(filename + '.jpg', newpath) # move image to new path.
shutil.move(filename + '.xml', newpath)
shutil.move(filename + '.txt', newpath)
import os
path = "G:\krunker\mod"
abcde = open("path.txt", "w")
for dirpath, dirnames, filenames in os.walk(path):
directory_level = dirpath.replace(path, "")
directory_level = directory_level.count(os.sep)
indent = " " * 4
print("{}{}/".format(indent*directory_level, os.path.basename(dirpath)), file=abcde)
for f in filenames:
print("{}{}".format(indent*(directory_level+1), f), file=abcde)
abcde.close()
I want it to print the files in every single folder of the path but it does only on the last
The indentation is not correct. The second for loop also has to be inside the first for loop.
Correct code:
import os
path = "/home/user/my_folder/tools"
abcde = open("path.txt", "w")
for dirpath, dirnames, filenames in os.walk(path):
directory_level = dirpath.replace(path, "")
directory_level = directory_level.count(os.sep)
indent = " " * 4
print("{}{}/".format(indent*directory_level, os.path.basename(dirpath)), file=abcde)
for f in filenames:
print("{}{}".format(indent*(directory_level+1), f), file=abcde)
abcde.close()
A part of path.txt content:
tools/
.gitignore
README.md
__init__.py
requirements3.txt
test.py
path.txt
.git/
description
hooks/
commit-msg.sample
info/
exclude
refs/
heads/
master
You can also use a recursive function which gets recursivly all subfolder's content until there's any subfolder:
from os import walk
output = open("path.txt", "w")
def listFiles(path, indent):
for (openedPath, folders, files) in walk(path):
for file in files:
output.write("\t" * (indent) + file + "\n")
for folder in folders:
output.write("\t" * (indent) + folder + "/\n")
listFiles(path + "/" + folder, indent + 1)
break
source = "/my/path/to/my/folder"
print(source + "/")
listFiles(source, 1)
There's an example with a little code project folder.
/my/path/to/my/folder/
input.txt
main.py
output/
error.cpp
trying.cpp
logo.cpp
You can use this kind of code to simplify
import os
folder = r"C:\path\to\find\files"
x = [os.path.join(r,file) for r,d,f in os.walk(folder) for file in f # If you want specific files if file.endswith(".txt")]
y = [os.path.join(r,folder) for r,d,f in os.walk(folder) for folder in d]
print(x) #For files in main directory and subdirectories
print(y) #For files in main directory and subdirectories
I've got 6 directories (A, B, C, D, E, F) containing .mov files.
The structure is:
A
-0001_01.mov
-0002_01.mov
-...
B
-0001_02.mov
-0002_02.mov
-...
And so on.
First, I want to create as many directories as there are files in one of the directories mentioned above.
Let's say A contains 35 .mov files (B, C .. contain the same amount of .mov files).
I now got 35 folders starting from "01" up to "35".
Now I want to copy each corresponding .mov file into the same directory, which means 0001_01.mov - 0001_06.mov go into "01", 0002_01.mov - 0002_06.mov go into "02" and so on.
I've got the creation of the directories working, but I just can't wrap my head around the copying part.
import os
pathA = ("./A/")
pathB = ("./B/")
pathC = ("./C/")
pathD = ("./D/")
pathE = ("./E/")
pathF = ("./F/")
path, dirs, filesA = next(os.walk(pathA))
file_countA = len(filesA)
path, dirs, filesB = next(os.walk(pathB))
file_countB = len(filesB)
path, dirs, filesC = next(os.walk(pathC))
file_countC = len(filesC)
path, dirs, filesD = next(os.walk(pathD))
file_countD = len(filesD)
path, dirs, filesE = next(os.walk(pathE))
file_countE = len(filesE)
path, dirs, filesF = next(os.walk(pathF))
file_countF = len(filesF)
path2 = ("./")
if file_countA == file_countB == file_countC == file_countD == file_countE == file_countF:
print("true")
else:
print ("false")
for i in range(file_countA):
try:
if i < 9:
os.mkdir(path2 + "0" + str(i + 1))
path3 = ("./" + "0" + str(i + 1))
print (path3)
elif i >= 9:
os.mkdir(path2 + str(i + 1))
path3 = ("./" + str(i + 1))
print (path3)
except OSError:
print ("Creation of the directory %s failed" % path2)
else:
print ("Successfully created the directory %s " % path2)
This is my first time using python, I think the code reflects that.
I've now wasted countless hours on this, so any help is appreciated.
So I changed your code quite a bit and tested it quickly on my system and it seemed to do what you wanted. Can you try and let me know if this gave you idea of how it can be done?
Disclaimer: I'm not Python expert by any means but I find my way around it and this is most likely not the prettiest solution but it deos work on my machine exactly as you wanted it. Just make sure you run it from inside your folder and if you are not running it from outside your folder then change cwd = os.getcwd() to cwd = "path-to-your-folder"
import os
import shutil
import glob
paths = ["/A/","/B/","/C/","/D/","/E/","/F/"]
cwd = os.getcwd()
num_folders = 0
for path in paths:
num_files = len([f for f in os.listdir(cwd+path)if os.path.isfile(os.path.join(cwd+path, f))])
if num_files>num_folders:
num_folders = num_files
for i in range(num_folders):
try:
if i < 9:
fname = cwd + "/0" + str(i + 1)
os.mkdir(fname)
for path in paths:
source = cwd + "/" + path
filename = "000{}_*.mov".format(i+1)
for file in glob.glob(os.path.join(source,filename)):
shutil.copy2(file,fname)
elif i >= 9:
fname = cwd + "/" + str(i + 1)
os.mkdir(fname)
for path in paths:
source = cwd + "/" + path
filename = "00{}_*.mov".format(i+1)
for file in glob.glob(os.path.join(source,filename)):
shutil.copy2(file,fname)
except OSError:
pass
I'm no python expert either (look at my scores too, hi), but I've tried to keep your original coding order as much as possible. I would recommend to look at different codes for real expert-tier code but it seems to do what you're asking for :
import os
import shutil
mov_pathes = ["./a/", "./b/"]
all_files = []
lengths = []
for mov_path in mov_pathes :
# listdir gives you all files in the direcetory
files_in_dir = os.listdir(mov_path)
# we'll save those in a list along with where it's from ,
# ex : ('./patha/',['0001_01.mov','0002_01.mov'])
all_files.append((mov_path, files_in_dir))
# also length info for "all items are equal length" comparison in the future
lengths.append(len(files_in_dir))
if lengths.count(lengths[0]) == len(lengths) :
print ("true")
else :
print ("false")
base_dir = "./"
for i in range (1,lengths[0]+1) :
try :
# zfill(n) fills rest of your string to 0, (ex. "7".zfill(5) gives you 00007), probably helpful for future
path_name = base_dir + str(i).zfill(2)
os.mkdir(path_name)
except OSError :
print ("Creation of the directory {path_name} failed".format(path_name = path_name))
else :
print ("Successfully created the directory {path_name}".format(path_name = path_name))
Does exactly the same thing but it would probably make maintaining your code easier laster on.
for your real question, IF we're sure that your inputs are gonna look like 00XX_NN.mov, adding
for files in all_files :
# Remember we saved as (original dir, list of files in the dir?)
# This is a original dir
source_dir = files[0]
# This is list of files in that directory
source_files = files[1]
for file in source_files :
# so original file is located in source_dir + file
source_file = source_dir + file
# and your target directory is 00XX, so getting file[2:4] gives the target directory
target_dir = base_dir + file[2:4]
#shutil.copy (source file, target directory) copies your files.
shutil.copy (source_file , target_dir)
seems to do what you're asking for, at least for me. Once again I'm no expert so let me know if it's not working!
tested with :
./a
- 0001_01
- 0002_01
- 0003_01
./b
- 0001_02
- 0002_02
- 0003_02
result :
./01 :
- 0001_01
- 0001_02
./02 :
- 0002_01
- 0002_02
./03 :
- 0003_01
- 0003_02
I have a small problem with a tool I built in Python.
This tool works classifying files by filenames and making folders by a word in every filename and then moving all the files to the corresponding folder.
Files:
09052019_6_filetype1_currenttime_randomnumber.xml
09052019_2_filetype2_currenttime_randomnumber.xml
09052019_9_filetype3_currenttime_randomnumber.xml
09052019_1_filetype3_currenttime_randomnumber.xml
09052019_1_filetype3_currenttime_randomnumber.xml
Actual results:
filetype1_Status_6(folder)
09052019_6_filetype1_currenttime_randomnumber.xml
filetype2_Status_2(folder)
09052019_2_filetype2_currenttime_randomnumber.xml
filetype3_Status_9(folder)
09052019_9_filetype3_currenttime_randomnumber.xml
filetype3_Status_1(folder)
09052019_1_filetype3_currenttime_randomnumber.xml
09052019_1_filetype3_currenttime_randomnumber.xml
Code Version 1.0
#!/usr/bin/python3
# v1.0
# Importing modules
import os
import shutil
import sys
# Path of input and output files
src = input('Input files: ')
dest = input('Destination files: ')
os.chdir(dest)
def classify():
for f in os.listdir(src):
splitname = f.split('_')
status = splitname[1]
topic = splitname[2]
foldername = topic + '_' + 'Status_' + status
if not os.path.exists(foldername):
os.mkdir(foldername)
shutil.move(os.path.join(src, f), foldername)
print('Sorting out files, please wait...')
classify()
print('¡DONE!')
Improvement
But in the v2.0 I would like to "improve" it a little more, just keeping the same usability but changing filenames from original name to "Message_*.xml" and it works but only moving one file, not all of them.
Current results:
filetype1_Status_6(folder)
Message_.xml
filetype2_Status_2(folder)
Message.xml
filetype3_Status_9(folder)
Message_.xml
filetype3_Status_1(folder)
Message_.xml
Expected results:
filetype1_Status_6(folder)
Message_.xml
filetype2_Status_2(folder)
Message.xml
filetype3_Status_9(folder)
Message_.xml
filetype3_Status_1(folder)
Message_.xml
Message_1.xml
Code Version 2.0
#!/usr/bin/python3
# v2.0
# Importing modules
import os
import shutil
import sys
# Path of input and output files
src = input('Input files: ')
dest = input('Destination files: ')
os.chdir(dest)
def classify():
for f in os.listdir(src):
splitname = f.split('_')
status = splitname[1]
topic = splitname[2]
foldername = topic + '_' + 'Status_' + status
newFileName = foldername + '\\' + 'Message_' + '.xml'
if not os.path.exists(foldername):
os.mkdir(foldername)
shutil.copy(os.path.join(src, f), newFileName)
print('Sorting out files, please wait...')
classify()
print('¡DONE!')
You are naming everything Message_ so you will never get multiple files. You need to parse the names in the folder and then increment the filenames accordingly.
msgName = 'Message_0'
newFileName = foldername + '\\' + msgName + '.xml'
if not os.path.exists(foldername):
os.mkdir(foldername)
else:
while os.path.isfile(newFileName) is True:
msgInt = int(msgName[8:])
msgInt += 1
msgName = msgName[:8] + str(msgInt)
newFileName = foldername + '\\' + msgName + '.xml'
shutil.copy(os.path.join(src, f), newFileName)
Now if you already have message_0.xml in your folder, you will get a message_1.xml instead, and so on.
This is one of my first python projects, and i'm trying to make a script that would write a script which can re-create the src/ directory. this would be what i distribute to users. It uses walk, and writes a python file that first creates all the directories, and then writes the files. The issue i have is making the the files into a single string that i can write to a file.
This is the program i have:
import os
import pickle
src = os.path.dirname(os.path.realpath(__file__)) + os.sep + 'src'
fPack = 'import os \nimport pickle \nmyDir = os.path.dirname(os.path.realpath(__file__))'
Pack =''
print 'Packing ' + src
pickle
for root, dirs, files in os.walk(src, topdown=True):
for name in files:
print os.path.join(root, name)
f = open(os.path.join(root, name), 'r')
Pack = Pack + '\nf = open(os.path.join(myDir,\'' + name + '\'), \'w\')'
fileCont = pickle.dumps(f.read())
Pack = Pack + '\nf.write(pickle.loads(\'' + fileCont + '\'))'
for name in dirs:
print os.path.join(root, name)
fPack = fPack + '\nos.makedirs(os.path.join(myDir,\'' + name + '\'))'
print '==================================================\n\n\n'
print fPack + Pack
f = open(os.getcwd() + os.sep + 'dist' + os.sep + 'Pack.py', 'w')
f.write(fPack)
f.write(Pack)
And if i run it in a directory with on subdirectory, and on file inside it creates this file
import os
import pickle
myDir = os.path.dirname(os.path.realpath(__file__))
os.makedirs(os.path.join(myDir,'SphereText'))
f = open(os.path.join(myDir,'TextMain.py'), 'w')
f.write(pickle.loads('S"########################################################\n#Main SphereText file. #\n#SpereText is a simple Notepad-Like plain text editor #\n########################################################\n\nfrom Tkinter import *\nfrom tkFileDialog import *\nimport tkSimpleDialog\n\nroot = Tk()\nroot.title('SphereText')\n\ndef fSave():\n fileName = asksaveasfilename(parent=root)\n f = open(fileName, 'w')\n f.write(text.get(1.0,END))\n\ndef fOpen():\n fileName = ''\n fileName = askopenfilename(parent=root)\n f = open(fileName, 'r')\n text.delete(1.0,END)\n text.insert(1.0, f.read())\n\ndef tReplace():\n Old = tkSimpleDialog.askstring('SphereText', 'Replace:')\n print Old\n New = tkSimpleDialog.askstring('SphereText', 'With:')\n print New\n content = text.get(1.0,END)\n content = content.replace(Old, New)\n text.delete(1.0,END)\n text.insert(1.0, content)\n \nmenubar = Menu(root)\nmenubar.add_command(label='Save', command=fSave)\nmenubar.add_command(label='Open', command=fOpen)\nmenubar.add_command(label='Replace', command=tReplace)\nroot.config(menu=menubar)\n\ntext = Text(root, wrap=WORD)\n\ntext.pack()\n\nroot.mainloop()\n"
p0
.'))
The 's aren't escaped, and there are two line breaks at the end. i thought that the whole point of serializing was that you could always read it back the same way. Anyone know how i can mak the file a valid string?
Sorry about the newbish question, i just found out i had been trying to reinvent the wheel. apparently, that already exists under the name Squeeze.