Python - Getting file directory as user input - python

Having some trouble getting a list of files from a user defined directory. The following code works fine:
inputdirectory = r'C:/test/files'
inputfileextensions = 'txt'
files = glob.glob(inputdirectory+"*."+inputfileextensions)
But I want to allow the user to type in the location. I've tried the following code:
inputdirectory = input("Please type in the full path of the folder containing your files: ")
inputfileextensions = input("Please type in the file extension of your files: ")
files = glob.glob(inputdirectory+"*."+inputfileextensions)
But it doesn't work. No error message occurs, but files returns as empty. I've tried typing in the directory with quotes, with forward and backward slashes but can't get it to work. I've also tried converting the input to raw string using 'r' but maybe by syntax is wrong. Any ideas?

Not quite sure how the first version works for you. The way the variables are defined, you should have the input to glob as something like:
inputdirectory+"*."+inputfileextensions == "C:\test\files*.txt"
Looking at the above value you can realize that its not something that you are trying to achieve. Instead, you need to join the two paths using the backslash operator. Something like:
os.path.join(inputdirectory, "*."+inputfileextensions) == "C:\test\files\*.txt"
With this change, the code should work regardless of whether the input is taken from the user or predefined.

Try to join path with os.path.join. It will handle slash issue.
import os
...
files = glob.glob(os.path.join(inputdirectory, "*."+inputfileextensions))

Working code for sample, with recursive search.
#!/usr/bin/python3
import glob
import os
dirname = input("What is dir name to search files? ")
path = os.path.join(dirname,"**")
for x in glob.glob(path, recursive=True):
print(x)

Related

How do I put a variable in a path

I'm trying to store a path in a variable. see below
target = r"C:\Users\User\CodeProjects\WebSafer"
However, I need it to be dynamic. Not hardcoded to my username, so I get the login username by doing:
val = os.getlogin()
So I need to put the variable val in the path. But every time I tried doing it I always get a truncating/syntax error. Please help me! Below is the code snippet:
print("No copy found...making a copy\n")
val = os.getlogin()
original = r"C:\*******\********\*******\***\****"
target = r"C:\Users\User\CodeProjects\WebSafer"
shutil.copy(original, target)
The "*" are just for privacy reasons, there actually replaced with the right path location to what I'm copying.
What I have tried so far:
target = r"C:\Users\{val}\CodeProjects\WebSafer".format(val = os.getlogin)
target = r"C:\Users\{}\CodeProjects\WebSafer".format(val)
target = rf"C:\Users\{val}\CodeProjects\WebSafer".format(val = os.getlogin)
target = rf"C:\Users\{}\CodeProjects\WebSafer".format(val)
Don't mix f with .format, this is working for me:
import os
val = os.getlogin()
print(rf"C:\Users\{val}\CodeProjects\WebSafer")
And I think better way is:
import os.path
from pathlib import Path
home = str(Path.home())
print(os.path.join(home, "CodeProjects\WebSafer"))
Then if you encounter some error when copying, you need clarify what you want to copy, copy a file, or a folder, if a folder, should it go to within the dest folder, or overwrite dest folder?
You may want try different methods such as
shutil.copy, shutil.copytree, and different parameters.
"r" means the string will be treated as raw string so try removing that and using escaped characters target = "C:\\Users\\{val}\\CodeProjects\\WebSafer".format(val = os.getlogin)
You can use f-string (to directly enter your variable) and r-string (to enter the path without escape characters like \) together.
val = os.getlogin() # Returns username
target = fr"C:\Users\{val}\CodeProjects\WebSafer"
If you're getting a No such file or directory error, it means that the actual file or folder does not exist. Check the actual path to ensure every part (Your Username, CodeProjects, Websafer) exists on your computer.
In case you don't know if your user will have that folder on their system, you can use a try-except block to alert the user or to revert to some default folder instead.

Make glob directory variable

I'm trying to write a Python script that searches a folder for all files with the .txt extension. In the manuals, I have only seen it hardcoded into glob.glob("hardcoded path").
How do I make the directory that glob searches for patterns a variable? Specifically: A user input.
This is what I tried:
import glob
input_directory = input("Please specify input folder: ")
txt_files = glob.glob(input_directory+"*.txt")
print(txt_files)
Despite giving the right directory with the .txt files, the script prints an empty list [ ].
If you are not sure whether a path contains a separator symbol at the end (usually '/' or '\'), you can concatenate using os.path.join. This is a much more portable method than appending your local OS's path separator manually, and much shorter than writing a conditional to determine if you need to every time:
import glob
import os
input_directory = input('Please specify input folder: ')
txt_files = glob.glob(os.path.join(input_directory, '*.txt'))
print(txt_files)
For Python 3.4+, you can use pathlib.Path.glob() for this:
import pathlib
input_directory = pathlib.Path(input('Please specify input folder: '))
if not input_directory.is_dir():
# Input is invalid. Bail or ask for a new input.
for file in input_directory.glob('*.txt'):
# Do something with file.
There is a time of check to time of use race between the is_dir() and the glob, which unfortunately cannot be easily avoided because glob() just returns an empty iterator in that case. On Windows, it may not even be possible to avoid because you cannot open directories to get a file descriptor. This is probably fine in most cases, but could be a problem if your application has a different set of privileges from the end user or from other applications with write access to the parent directory. This problem also applies to any solution using glob.glob(), which has the same behavior.
Finally, Path.glob() returns an iterator, and not a list. So you need to loop over it as shown, or pass it to list() to materialize it.

Using input to change directory path

I'm kinda new to python and I feel like the answer to this is so simple but I have no idea what the answer is. I'm trying to move files from one place to another but I don't want to have to change my code every time I wanna move that file so I just want to get user input from the terminal.
import shutil
loop = True
while loop:
a = input()
shutil.move("/home/Path/a", "/home/Path/Pictures")
What do I have to put around the a so that it doesn't read it as part of the string?
This should do what you want. the os.path.join() will combine the string value in a, that you get from input with the first part of the path you have provided. You should use os.path.join() as this will form paths in a way that is system independent.
import shutil
import os
loop = True
while loop:
a = input()
shutil.move(os.path.join("/home/Path/", a), "/home/Path/Pictures")
Output:
>>> a = input()
test.txt
>>> path = os.path.join("/home/Path/", a)
>>> path
'/home/Path/test.txt'
You can also use "/home/Path/{0}".format(a) which will swap the value of a with {0}, or you can do do "/home/Path/{0}" + str(a) which will also do what you want.
Edited to account for Question in comment:
This will work if your directory doesn't have any sub-directories. it may still work if there are directories and files in there but I didn't test that.
import shutil
import os
files = os.listdir("/home/Path/")
for file in files:
shutil.move(os.path.join("/home/Path/", file), "/home/Path/Pictures")
one solution
a = 'test.csv'
path = '/home/Path/{}'.format(a)
>>> path
/home/Path/test.csv

How to insert strings and slashes in a path?

I'm trying to extract tar.gz files which are situated in diffent files named srm01, srm02 and srm03.
The file's name must be in input (a string) to run my code.
I'm trying to do something like this :
import tarfile
import glob
thirdBloc = 'srm01' #Then, that must be 'srm02', or 'srm03'
for f in glob.glob('C://Users//asediri//Downloads/srm/'+thirdBloc+'/'+'*.tar.gz'):
tar = tarfile.open(f)
tar.extractall('C://Users//asediri//Downloads/srm/'+thirdBloc)
I have this error message:
IOError: CRC check failed 0x182518 != 0x7a1780e1L
I want first to be sure that my code find the .tar.gz files. So I tried to just print my paths after glob:
thirdBloc = 'srm01' #Then, that must be 'srm02', or 'srm03'
for f in glob.glob('C://Users//asediri//Downloads/srm/'+thirdBloc+'/'+'*.tar.gz'):
print f
That gives :
C://Users//asediri//Downloads/srm/srm01\20160707000001-server.log.1.tar.gz
C://Users//asediri//Downloads/srm/srm01\20160707003501-server.log.1.tar.gz
The os.path.exists method tell me that my files doesn't exist.
print os.path.exists('C://Users//asediri//Downloads/srm/srm01\20160707000001-server.log.1.tar.gz')
That gives : False
Any way todo properly this work ? What's the best way to have first of all the right paths ?
In order to join paths you have to use os.path.join as follow:
import os
import tarfile
import glob
thirdBloc = 'srm01' #Then, that must be 'srm02', or 'srm03'
for f in glob.glob(os.path.join('C://Users//asediri//Downloads/srm/', thirdBloc, '*.tar.gz'):
tar = tarfile.open(f)
tar.extractall(os.path.join('C://Users//asediri//Downloads/srm/', thirdBloc))
os.path.join will create the correct paths for your filesystem
f = os.path.join('C://Users//asediri//Downloads/srm/', thirdBloc, '*.tar.gz')
C://Users//asediri//Downloads/srm/srm01\20160707000001-server.log.1.tar.gz
Never use \ with python for filepaths, \201 is \x81 character. It results to this:
C://Users//asediri//Downloads/srm/srm01ΓΌ60707000001-server.log.1.tar.gz
this is why os.path.exists does not find it
Or use (r"C:\...")
I would suggest you do this:
import os
os.chdir("C:/Users/asediri/Downloads/srm/srm01")
for f in glob.glob(str(thirdBloc) + ".tar.gz"):
print f

Generalize a program using iglob

I have a program which scans a folder or path for a given type of files and then analyze them.
import glob
path = raw_input("ENTER PATH TO SEARCH: ")
list_of_file = glob.iglob('*.txt')
for filename in list_of_file:
print filename`
But in this script the program will scan the directory only in which it was stored in path statement gets no value.
Now if I write:
list_of_file = glob.iglob(path + '*.txt')
this also do not make my work going.
So please suggest a way in which whatever path I enter the program follows that path and search for particular file types, no matter where I kept my script.
I assume English is not your first language, so please forgive me if I have misunderstood your question. It seems to me that you want to be able to enter a directory and then find all the ".txt" files in that directory?
If so, then the following code should suffice to give you an example:
"""Find all .py files is a given directory."""
import os
import glob
path = raw_input("Enter path: ")
fullglob = os.path.join(path, "*.py")
for fn in glob.iglob(fullglob):
print os.path.split(fn)[1]
The last line takes off the path you put in to ensure iglob() finds the right directory. You can use the help() function to get documentation on os.path.join() and os.path.split().

Categories

Resources