4

I want to search a string from multiple files

What I tried:

import os
path= 'sample1/nvram2/logs' 
all_files=os.listdir(path) 
for my_file1 in all_files:
    print(my_file1)
    with open(my_file1, 'r') as my_file2:
        print(my_file2)
        for line in my_file2:
            if 'string' in line:
                print(my_file2)

Output:

C:\Users\user1\scripts>python search_string_3.py
abcd.txt
Traceback (most recent call last):
  File "search_string_3.py", line 6, in <module>
    with open(my_file1, 'r') as my_file2:
FileNotFoundError: [Errno 2] No such file or directory: 'abcd.txt'

But file abcd.txt is present in C:\Users\user1\scripts\sample1\nvram2\logs

Why the Error shows that No such file or directory?

Using glob:

The following error was displayed when I use all_files=glob.glob(path) instead of all_files=os.listdir(path)

C:\Users\user1\scripts>python search_string_3.py
sample1/nvram2/logs
Traceback (most recent call last):
  File "search_string_3.py", line 7, in <module>
    with open(my_file1, 'r') as my_file2:
PermissionError: [Errno 13] Permission denied: 'sample1/nvram2/logs'
Dipankar Nalui
  • 1,121
  • 5
  • 18
  • 33
  • In your own words, where the code says `with open(my_file1, 'r') as my_file2:`, why do you expect that it should look in the `C:\Users\user1\scripts\sample1\nvram2\logs` folder for the file? – Karl Knechtel Jul 19 '23 at 03:20
  • "The following error was displayed when I use all_files=glob.glob(path)" - notice how the output of the `print(my_file1)` line is different? That should point to a misunderstanding of what the `glob` does. – Karl Knechtel Jul 19 '23 at 03:25

1 Answers1

3

you figured out/guessed the first issue. Joining the directory with the filename solves it. A classic:

with open(os.path.join(path,my_file1), 'r') as my_file2:

I wouldn't have cared to answer if you didn't attempt something with glob. Now:

for x in glob.glob(path):

since path is a directory, glob evaluates it as itself (you get a list with one element: [path]). You need to add a wildcard:

for x in glob.glob(os.path.join(path,"*")):

The other issue with glob is that if the directory (or the pattern) doesn't match anything you're not getting any error. It just does nothing... The os.listdir version crashes at least.

and also test if it's a file before opening (in both cases) because attempting to open a directory results in an I/O exception:

if os.path.isfile(x):
  with open ...

In a nutshell os.path package is your friend when manipulating files. Or pathlib if you like object-oriented path manipulations.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219