Finished
11def grep(pattern: str, flags: str, files: list[str]) -> str:
2 pass
2 """
3 Search for lines matching a pattern in files and return matching lines.
4
5 Args:
6 pattern: The string to search for
7 flags: String containing command line flags (-n, -l, -i, -v, -x)
8 files: List of file paths to search in
9
10 Returns:
11 String containing matching lines, formatted according to flags
12
13 Edge Cases Handled:
14 - Empty files list
15 - File not found
16 - Empty pattern
17 - Pattern not found in any files
18 - Multiple flags combined
19 - Case insensitive matching
20 - Exact line matching
21 - Line inversion
22 - Line numbering
23 - File name output only
24 """
25 # Edge Case: Empty files list
26 if not files:
27 return ""
28
29 # Parse flags
30 line_numbers = '-n' in flags
31 files_only = '-l' in flags
32 case_insensitive = '-i' in flags
33 invert_match = '-v' in flags
34 exact_match = '-x' in flags
35
36 # Prepare pattern for comparison
37 search_pattern = pattern.lower() if case_insensitive else pattern
38
39 results = []
40 matching_files = set()
41
42 # Edge Case: Process each file
43 for file_path in files:
44 try:
45 with open(file_path, 'r', encoding='utf-8') as file:
46 lines = file.readlines()
47
48 # Edge Case: Process each line in the file
49 for line_num, line in enumerate(lines, 1):
50 # Prepare line for comparison
51 compare_line = line.lower() if case_insensitive else line
52
53 # Determine if line matches
54 if exact_match:
55 matches = search_pattern == compare_line.rstrip('\n')
56 else:
57 matches = search_pattern in compare_line
58
59 # Edge Case: Apply invert flag
60 if invert_match:
61 matches = not matches
62
63 # Edge Case: Handle matching line
64 if matches:
65 matching_files.add(file_path)
66
67 # Edge Case: If only file names requested, no need to collect lines
68 if not files_only:
69 output_line = line
70
71 # Edge Case: Format output with filename if multiple files
72 if len(files) > 1:
73 output_line = f"{file_path}:{output_line}"
74
75 # Edge Case: Add line number if requested
76 if line_numbers:
77 # Find the position to insert line number (after filename if present)
78 if len(files) > 1:
79 colon_pos = output_line.find(':')
80 output_line = f"{output_line[:colon_pos+1]}{line_num}:{output_line[colon_pos+1:]}"
81 else:
82 output_line = f"{line_num}:{output_line}"
83
84 results.append(output_line)
85 except FileNotFoundError:
86 # Edge Case: File not found - continue with other files
87 continue
88
89 # Edge Case: If files only flag is set, return only file names
90 if files_only:
91 # Return files in the order they were specified, but only those that had matches
92 output_files = [f for f in files if f in matching_files]
93 return '\n'.join(output_files) + ('\n' if output_files else '')
94
95 # Edge Case: Join results with newlines
96 return ''.join(results)
97
98# Handled Edge Cases: Empty files list, File not found, Empty pattern, Pattern not found in any files, Multiple flags combined, Case insensitive matching, Exact line matching, Line inversion, Line numbering, File name output only
Test NameStatus
test_multiple_files_no_matches_various_flags
Pass
test_multiple_files_one_match_match_entire_lines_flag
Pass
test_multiple_files_one_match_multiple_flags
Pass
test_multiple_files_one_match_no_flags
Pass
test_multiple_files_one_match_print_file_names_flag
Pass
test_multiple_files_several_matches_case_insensitive_flag
Pass
test_multiple_files_several_matches_file_flag_takes_precedence_over_line_number_flag
Pass
test_multiple_files_several_matches_inverted_and_match_entire_lines_flags
Pass
test_multiple_files_several_matches_inverted_flag
Pass
test_multiple_files_several_matches_no_flags
Pass
test_multiple_files_several_matches_print_line_numbers_flag
Pass
test_one_file_no_matches_various_flags
Pass
test_one_file_one_match_case_insensitive_flag
Pass
test_one_file_one_match_file_flag_takes_precedence_over_line_flag
Pass
test_one_file_one_match_match_entire_lines_flag
Pass
test_one_file_one_match_multiple_flags
Pass
test_one_file_one_match_no_flags
Pass
test_one_file_one_match_print_file_names_flag
Pass
test_one_file_one_match_print_line_numbers_flag
Pass
test_one_file_several_matches_case_insensitive_flag
Pass
test_one_file_several_matches_inverted_and_match_entire_lines_flags
Pass
test_one_file_several_matches_inverted_flag
Pass
test_one_file_several_matches_match_entire_lines_flag
Pass
test_one_file_several_matches_no_flags
Pass
test_one_file_several_matches_print_line_numbers_flag
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.