Hi everyone I have a small issue with a script I wrote.
import os
import glob
def loop_dir():
for file in glob.glob('/Users/++++/+++/test/*.mp4'):
return str(file).split('/')[-1]
def mk_dir():
i=1
keepGoing=True
while keepGoing:
path = "Folder_{}/".format(i)
if not os.path.exists(path):
os.makedirs(os.path.dirname("Folder_{}/".format(i)), exist_ok=False)
keepGoing = False
i += 1
return str(path)
with os.scandir('/Users/++++/++++/test') as it:
for vid in it:
os.system('python3 video2images.py \. #here goes the filename
-i /Users/++++/++++/test/' + loop_dir() + ' \
-o /Users/++++/++++/' + mk_dir() + ' \
--sample_interval 2 \
--max_frames 100')
What I would like to do here is to have the first function return one by one the filenames in the directory so they can be inserted in the last chunk at the bottom.
I have tried several options os.listdir() os.scandir() glob.iglob() but I couldn't fix my issue. At the moment the code always loops using the same filename.
Thanks in advance for the help!
The reason its return one file its because of the logical error your making in the loop.
I suggest you append the files found to an array then return the array. You can then access the files from the array.
def loop_dir():
files=[]
for file in glob.glob('/Users/++++/+++/test/*.mp4'):
files.append(str(file).split('/')[-1])
return files
Related
I have a text file (filenames.txt) that contains the file name with its file extension.
filename.txt
[AW] One Piece - 629 [1080P][Dub].mkv
EP.585.1080p.mp4
EP609.m4v
EP 610.m4v
One Piece 0696 A Tearful Reunion! Rebecca and Kyros!.mp4
One_Piece_0745_Sons'_Cups!.mp4
One Piece - 591 (1080P Funi Web-Dl -Ks-)-1.m4v
One Piece - 621 1080P.mkv
One_Piece_S10E577_Zs_Ambition_A_Great_and_Desperate_Escape_Plan.mp4
these are the example filename and its extension. I need to rename filename with the episode number (without changing its extension).
Example:
Input:
``````
EP609.m4v
EP 610.m4v
EP.585.1080p.mp4
One Piece - 621 1080P.mkv
[AW] One Piece - 629 [1080P][Dub].mkv
One_Piece_0745_Sons'_Cups!.mp4
One Piece 0696 A Tearful Reunion! Rebecca and Kyros!.mp4
One Piece - 591 (1080P Funi Web-Dl -Ks-)-1.m4v
One_Piece_S10E577_Zs_Ambition_A_Great_and_Desperate_Escape_Plan.mp4
Expected Output:
````````````````
609.m4v
610.m4v
585.mp4
621.mkv
629.mkv
745.mp4 (or) 0745.mp4
696.mp4 (or) 0696.mp4
591.m4v
577.mp4
Hope someone will help me parse and rename these filenames. Thanks in advance!!!
As you tagged python, I guess you are willing to use python.
(Edit: I've realized a loop in my original code is unnecessary.)
import re
with open('filename.txt', 'r') as f:
files = f.read().splitlines() # read filenames
# assume: an episode comprises of 3 digits possibly preceded by 0
p = re.compile(r'0?(\d{3})')
for file in files:
if m := p.search(file):
print(m.group(1) + '.' + file.split('.')[-1])
else:
print(file)
This will output
609.m4v
610.m4v
585.mp4
621.mkv
629.mkv
745.mp4
696.mp4
591.m4v
577.mp4
Basically, it searches for the first 3-digit number, possibly preceded by 0.
I strongly advise you to check the output; in particular, you would want to run sort OUTPUTFILENAME | uniq -d to see whether there are duplicate target names.
(Original answer:)
p = re.compile(r'\d{3,4}')
for file in files:
for m in p.finditer(file):
ep = m.group(0)
if int(ep) < 1000:
print(ep.lstrip('0') + '.' + file.split('.')[-1])
break # go to next file if ep found (avoid the else clause)
else: # if ep not found, just print the filename as is
print(file)
Program to parse episode number and renaming it.
Modules used:
re - To parse File Name
os - To rename File Name
full/path/to/folder - is the path to the folder where your file lives
import re
import os
for file in os.listdir(path="full/path/to/folder/"):
# searches for the first 3 or 4 digit number less than 1000 for each line.
for match_obj in re.finditer(r'\d{3,4}', file):
episode = match_obj.group(0)
if int(episode) < 1000:
new_filename = episode.lstrip('0') + '.' + file.split('.')[-1]
old_name = "full/path/to/folder/" + file
new_name = "full/path/to/folder/" + new_filename
os.rename(old_name, new_name)
# go to next file if ep found (avoid the else clause)
break
else:
# if episode not found, just leave the filename as it is
pass
I have a list of files that I wish to rename to.
Receipt ABC-001 623572349-1.txt --> Receipt ABC-001A.txt
Receipt ABC-001 623572349-2.txt --> Receipt ABC-001B.txt
However, even at the first step, everytime I get the following error "Cannot create a file when that file already exists:". What would be the best option to achieve the above outcome where files ending with 1 will become A; ending with 5.txt will become E.txt, and soforth?
Below is the code I have used:
import os, fnmatch
#Set directory of locataion; include double slash for each subfolder.
file_path = "C:\\Users\\Mr.Slowbro\\Desktop\\TBU\\"
#Set file extension accordingly
files_to_rename = fnmatch.filter(os.listdir(file_path), '*.txt')
for file_name in files_to_rename:
file_name_new = file_name[-5:5]
os.rename(file_path + file_name, file_path + file_name_new)
This should help you out. Using the ord() function returns the Unicode point of a character. So 'a' would be 97, 'b' would be 98, etc. Likewise, chr() returns the character of that Unicode point. So, I think the code below will help you with your issue.
#Set directory of locataion; include double slash for each subfolder.
file_path = "C:\\Users\\Mr.Slowbro\\Desktop\\TBU\\"
#Set file extension accordingly
files_to_rename = fnmatch.filter(os.listdir(file_path), '*.txt')
for file_name in files_to_rename:
number = chr(int(file_name[-5]) - 1 + ord('A'))
file_name_new = 'Receipt ABC-001' + number + '.txt'
os.rename(file_name, file_name_new)```
Well I am currently facing a weird issue where my filename (which is correctly generated is overwritten with something random).
I am using this code to upload to AWS3, here the code checks wether a file with such name exists already in the bucket and if it does, it adds a 1 to the end of the file, then it keeps checking for existing files and increments the number until the filename is unique.
I tested the code in a seperate python file and it seemed to work fine, but here my filename is overwritten with random stringname b1.a
I was debugging now for a while and I have no clue. I remember having something similar a while ago, where a missing favicon caused the issue (probably someone knows what was going on and how these issues are connected). But this time I cant figure out what happened.
k.key = bucketpath + filename_hauptbild
if k.key in bucket:
new_filename_haupt_split = filename_hauptbild.split(".")
while k.key in bucket:
if new_filename_haupt_split[0][-1] not in "0123456789":
new_filename_haupt = new_filename_haupt_split[0] + "1." + new_filename_haupt_split[1]
else:
new_filename_haupt = new_filename_haupt_split[0][:-1] + str(int(new_filename_haupt_split[0][-1]) + 1) + "." + new_filename_haupt_split[1]
new_filename_haupt_split = new_filename_haupt
k.key = bucketpath + new_filename_haupt
print "this", new_filename_haupt
k.key = bucketpath + new_filename_haupt
filename_hauptbild = new_filename_haupt
k.set_contents_from_string(file_contents)
else:
k.set_contents_from_string(file_contents)
print filename_hauptbild
setattr(model_to_change, model_column, filename_hauptbild)
Notice here:
I use 2 x prints and the output shows 3 lines.
The first print "this", new_filename_haupt shows initialy the correct filename but is overwritten by b1.a:
Console output:
When you update your filename, you don't properly update your _split variable:
new_filename_haupt_split = new_filename_haupt
hence, on the next loop when you call new_filename_haupt_split[0] you just get the first letter of the filename - b - rather than the filename itself, and when you call new_filename_haupt_split[1] you get the second letter - a - rather than the extension. Hence the name b1.a. Change your line to:
new_filename_haupt_split = new_filename_haupt.split(".")
and I think this should work.
EDIT: you could re-write this as a function to make your life a little easier. Here's an example of the kind of approach you might require:
bucket = ['baubedarf.png', 'baubedarf1.png']
def get_filename(input_filename, all_files):
if input_filename in all_files:
filename, ext = input_filename.rsplit('.', 1)
counter = 1
while '{}{}.{}'.format(filename, counter, ext) in all_files:
counter += 1
return '{}{}.{}'.format(filename, counter, ext)
else:
return input_filename
print get_filename('baubedarf.png', bucket)
I am writing a Python 2 program to find a file. This program should print each directory it searches at each iteration of the search, but always to the same line in the terminal (i.e. by erasing the text that is already there and moving the cursor to the beginning of the line before printing again.)
This is the code I have so far:
import os
import sys
for root, dirs, files in os.walk("/"):
print root +'\r',
print '\x1b[2K\r',
My problem is that it starts each printout (when it change directory) on a new line; in other words, it doesn't reuse the old line.
How can I ensure all printed output goes to a single line in the terminal?
You need to flush the stdout buffer (depends on the terminal system), and pad the line with whitespace. For example:
for root, dirs, files in os.walk(path):
print "%-80s\r" % (root),
sys.stdout.flush()
time.sleep(1) # For testing
This assumes an arbitrary maximum filename length of 80 characters.
EDIT:
This new solution uses curses, which is part of the standard library:
import curses
import os
import time
win = curses.initscr()
for root, dirs, files in os.walk(path):
win.clear()
win.addstr(0, 0, root)
win.refresh()
time.sleep(1) # For testing purposes
curses.endwin()
This should do it.
for root, dirs, files in os.walk(path):
print '\r', root,
The \r tells python to rewind to the beginning of the current line, like old typewriters.
You might want to pad with spaces to erase the rest of the line, if the current path is shorter than the previous path.
If the text is longer than one line, it will still overflow to the next line.
You need to shorten your output to under the terminal limit.
You could just truncate and put ellipsis at the front:
limit = 30 # for example
message = 'ABCDEFGHIJKLMNOPQRSTUVWX' * 4
if len(message) > limit:
message = '...' + message[-limit+3:]
print message # ...VWXABCDEFGHIJKLMNOPQRSTUVWX
If you want to replace the middle with ..., then you could do:
limit = 30 # for example
message = 'ABCDEFGHIJKLMNOPQRSTUVWX' * 4
length = len(message) # will be 100
if length > limit:
message = list(message)
cut_size = length - limit
start_cut = (length - cut_size) / 2
message[start_cut:start_cut + cut_size + 3] = '...'
message = ''.join(message)
print message # ABCDEFGHIJKLMNO...MNOPQRSTUVWX
Inspired by several ideas from here and there, this works for me well:
import os
import sys
import time # only if you use sleep() function for debugging
top_folder = "/"
max_line_length = 80
for root, dirs, files in os.walk(top_folder):
message = root
# truncate if the path longer than what you want it to be
if len(message) > max_line_length:
message = '[...]' + message[-max_line_length+5:]
# prepare the output string of lenght determined by a variable
output_string = '{0: <' + str(max_line_length) + '}\r' # \r = carret return
# output
print output_string.format(message), # the comma is crucial here
# to see it in action in slow-motion
time.sleep(.4)
The last 2 code lines before the sleep() function line could be combined into one line:
print '{msg: <{width}}\r'.format(msge = message, width = max_line_length),
I have a large list of images that have been misnamed by my artist. I was hoping to avoid giving him more work by using Automator but I'm new to it. Right now they're named in order what001a and what002a but that should be what001a and what001b. So basically odd numbered are A and even numbered at B. So i need a script that changes the even numbered to B images and renumbers them all to the proper sequential numbering. How would I go about writing that script?
A small Ruby script embedded in an AppleScript provides a very comfortable solution, allowing you to select the files to rename right in Finder and displaying an informative success or error message.
The algorithm renames files as follows:
number = first 3 digits in filename # e.g. "006"
letter = the letter following those digits # e.g. "a"
if number is even, change letter to its successor # e.g. "b"
number = (number + 1)/2 # 5 or 6 => 3
replace number and letter in filename
And here it is:
-- ask for files
set filesToRename to choose file with prompt "Select the files to rename" with multiple selections allowed
-- prepare ruby command
set ruby_script to "ruby -e \"s=ARGV[0]; m=s.match(/(\\d{3})(\\w)/); n=m[1].to_i; a=m[2]; a.succ! if n.even?; r=sprintf('%03d',(n+1)/2)+a; puts s.sub(/\\d{3}\\w/,r);\" "
tell application "Finder"
-- process files, record errors
set counter to 0
set errors to {}
repeat with f in filesToRename
try
do shell script ruby_script & (f's name as text)
set f's name to result
set counter to counter + 1
on error
copy (f's name as text) to the end of errors
end try
end repeat
-- display report
set msg to (counter as text) & " files renamed successfully!\n"
if errors is not {} then
set AppleScript's text item delimiters to "\n"
set msg to msg & "The following files could NOT be renamed:\n" & (errors as text)
set AppleScript's text item delimiters to ""
end if
display dialog msg
end tell
Note that it will fail when the filename contains spaces.
A friend of mine wrote a Python script to do what I needed. Figured I'd post it here as an answer for anyone stumbling upon a similar problem looking for help. It is in Python though so if anyone wants to convert it to AppleScript for those that may need it go for it.
import os
import re
import shutil
def toInt(str):
try:
return int(str)
except:
return 0
filePath = "./"
extension = "png"
dirList = os.listdir(filePath)
regx = re.compile("[0-9]+a")
for filename in dirList:
ext = filename[-len(extension):]
if(ext != extension): continue
rslts = regx.search(filename)
if(rslts == None): continue
pieces = regx.split(filename)
if(len(pieces) < 2): pieces.append("")
filenumber = toInt(rslts.group(0).rstrip("a"))
newFileNum = (filenumber + 1) / 2
fileChar = "b"
if(filenumber % 2): fileChar = "a"
newFileName = "%s%03d%s%s" % (pieces[0], newFileNum, fileChar, pieces[1])
shutil.move("%s%s" % (filePath, filename), "%s%s" % (filePath, newFileName))