Home > Mobile >  Seach a directory for a file that fits a filemask, search it line by line for specific text and retu
Seach a directory for a file that fits a filemask, search it line by line for specific text and retu

Time:07-30

In Python, its the vagueness that I struggle with.

Lets start with what I know. I know that I want to search a specific directory for a file. And I want to search that file for a specific line that contains a specific string, and return only that line.

Which brings me to what I don't know. I have a vague description of the specific filename: some_file_{variable}_{somedatestamp}_{sometimestamp}.log So I know the file will start with some_file followed by a known variable and ending in .log. I don't know the date stamp or the time stamp. And to top it off, the file might not still exist at the time of searching, so I need to cover for that eventuality.

To better describe the problem, I have the line of the BASH script that accomplishes this: ls -1tr /dir/some_file_${VARIABLE}_*.log | tail -2 | xargs -I % grep "SEARCH STRING" %

So basically, I want to recreate that line of code from the BASH script in Python, and throw a message in the case that the search returns no files.

CodePudding user response:

See if this works for you:

from glob import glob
import os

log_dir = 'C:\\Apps\\MyApp\\logs\\'

log_variable = input("Enter variable:")
filename = "some_file" log_variable

# Option 1
searched_files1 = glob(log_dir filename '*.log')
print(f'Total files found = {len(searched_files1)}')
print(searched_files1)


# Option 2
searched_files2 = []
for object in os.listdir(log_dir):
    if (os.path.isfile(os.path.join(log_dir,object)) and object.startswith(filename) and object.endswith('.log')):
        searched_files2.append(object)
print(f'Total files found = {len(searched_files2)}')
print(searched_files2)

CodePudding user response:

Some variant of this will work. This will work for an arbitrary folder structure and will search all subfolders.... results will hold path to directory, filename, and txt, line number (1-based).

Some key pieces:

  • os.walk is beautiful for searching directory trees. The top= can be relative or absolute
  • use a context manager with ... as ... to open files as it closes them automatically
  • python iterates over text-based files in line-by line format

Code

from os import walk, path

magic_text = 'lucky charms'
results = []

for dirpath, _, filenames in walk(top='.'):
    for f in filenames:
        # check the name.  can use string methods or indexing...
        if f.startswith('some_name') and f[-4:] == '.log':
            # read the lines and look for magic text
            with open(path.join(dirpath, f), 'r') as src:
                # if you iterate over a file, it returns line-by-line
                for idx, line in enumerate(src):
                    # strings support the "in" operator...
                    if magic_text in line:
                        results.append((dirpath, f, idx 1, line))

for item in results:
    print(f'on path {item[0]} in file {item[1]} on line {item[2]} found: {item[3]}')

In a trivial folder tree, I placed the magic words in one file and got this result:

on path ./subfolder/subsub in file some_name_331a.log on line 2 found: lucky charms are delicious
  • Related