Konoha

Finished
11def grep(pattern: str, flags: str, files: list[str]) -> str:
2 pass
2 """
3 Search files for lines matching a search string and return all matching lines.
4
5 Args:
6 pattern: The string to search for
7 flags: Space-separated string of flags (-n, -l, -i, -v, -x)
8 files: List of file paths to search in
9
10 Returns:
11 String containing all matching lines, formatted according to flags
12 """
13 # Parse flags
14 flag_list = flags.split() if flags else []
15 line_numbers = '-n' in flag_list
16 files_only = '-l' in flag_list
17 case_insensitive = '-i' in flag_list
18 invert_match = '-v' in flag_list
19 exact_match = '-x' in flag_list
20
21 # Edge Case: No files provided
22 if not files:
23 return ""
24
25 # Edge Case: Pattern is empty
26 if not pattern:
27 exact_match = False # Disable exact match if pattern is empty
28
29 results = []
30 matching_files = set()
31
32 # Determine search pattern based on case sensitivity
33 search_pattern = pattern.lower() if case_insensitive else pattern
34
35 # Process each file
36 for file_path in files:
37 # Edge Case: File cannot be opened or does not exist
38 try:
39 with open(file_path, 'r', encoding='utf-8') as file:
40 lines = file.readlines()
41 except (FileNotFoundError, IOError, UnicodeDecodeError):
42 # Skip files that cannot be read
43 continue
44
45 file_has_match = False
46
47 # Process each line in the file
48 for line_num, line in enumerate(lines, 1):
49 # Determine line content for comparison based on case sensitivity
50 compare_line = line.lower().rstrip('\n') if case_insensitive else line.rstrip('\n')
51
52 # Determine if line matches based on search criteria
53 if exact_match:
54 line_matches = (compare_line == search_pattern)
55 else:
56 line_matches = (search_pattern in compare_line)
57
58 # Apply invert flag
59 if invert_match:
60 line_matches = not line_matches
61
62 # Edge Case: Empty pattern should match empty lines when not using exact match
63 if not pattern and not exact_match:
64 line_matches = True
65
66 if line_matches:
67 file_has_match = True
68
69 # If we only need file names, we can break early
70 if files_only:
71 matching_files.add(file_path)
72 break
73
74 # Build output line
75 output_line = ""
76
77 # Add filename prefix if multiple files
78 if len(files) > 1:
79 output_line += f"{file_path}:"
80
81 # Add line number if requested
82 if line_numbers:
83 output_line += f"{line_num}:"
84
85 # Add the actual line content
86 output_line += line
87
88 results.append(output_line)
89
90 # If we're only outputting filenames and this file had a match
91 if files_only and file_has_match:
92 matching_files.add(file_path)
93
94 # Edge Case: No matches found
95 if files_only:
96 return "\n".join(sorted(matching_files)) + ("\n" if matching_files else "")
97
98 # Edge Case: No results to return
99 if not results:
100 return ""
101
102 return "".join(results)
103
104# Handled Edge Cases: No files provided, Pattern is empty, File cannot be opened or does not exist, Empty pattern should match empty lines when not using exact match, No matches found, No results to return
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.