-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsshark
More file actions
executable file
·150 lines (128 loc) · 6.78 KB
/
Copy pathsshark
File metadata and controls
executable file
·150 lines (128 loc) · 6.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/usr/bin/env python3
import os
import re
import sys
import platform
from colorama import Fore, Style
# Function to colorize matched keyword for terminal output (Linux and macOS support colors)
def colorize_keyword(line, keyword):
if platform.system() in ['Linux', 'Darwin']:
return re.sub(f"({keyword})", r"\033[91m\1\033[0m", line)
else: # Windows
return line # Colorizing in the terminal doesn't work by default on Windows
def colorize_replacement(replacement):
if platform.system() in ['Linux', 'Darwin']:
return f"\033[92m{replacement}\033[0m"
else: # Windows (if colors aren't supported)
return replacement
def search_and_replace(keyword, match_mode, search_path, replace=None):
matches_found = False # Variable to track if any matches are found
print(f"Searching for keyword: {keyword} in {search_path} with mode: {match_mode}")
# Recursively traverse directories and subdirectories
for root, dirs, files in os.walk(search_path):
for file in files:
file_path = os.path.join(root, file)
# print(f"Checking file: {file_path}")
try:
# Try opening the file with UTF-8 encoding and check for decoding errors
with open(file_path, 'r', encoding='utf-8', errors='strict') as f:
lines = f.readlines()
except UnicodeDecodeError:
# Skip the file if it's not UTF-8
# print(f"🔴 Skipping non-UTF-8 file: {file_path}")
continue # Skip to the next file
except Exception as e:
# print(f"🔴 Error opening file {file_path}: {e}")
continue # Ignore files that can't be opened
found = False
new_lines = []
for line_number, line in enumerate(lines, 1):
match = None
# Handle different matching modes
if match_mode in ['-md', '']: # Match default (no case sensitivity, partial)
match = re.search(re.escape(keyword), line, re.IGNORECASE)
elif match_mode == '-mc': # Match case-sensitive
match = re.search(re.escape(keyword), line)
elif match_mode == '-mw': # Match whole word (case-insensitive)
match = re.search(rf'\b{re.escape(keyword)}\b', line, re.IGNORECASE)
elif match_mode == '-me': # Match both case-sensitive and whole word
match = re.search(rf'\b{re.escape(keyword)}\b', line)
if found and replace:
# Write changes back to the file
try:
with open(file_path, 'w', encoding='utf-8', errors='ignore') as f:
f.writelines(new_lines)
except Exception as e:
print(f"🔴 Error writing to file {file_path}: {e}")
continue # Ignore files that can't be written to
# If no matches were found, print a colored message
if not matches_found:
print(f"\n 🔴 No matches found for the keyword: {Fore.GREEN}{keyword}{Style.RESET_ALL}")
def print_help():
logo = f'''
{Fore.BLUE}.dP"Y8 888888 88""Yb 88 88b 88 dP""b8 {Fore.CYAN}.dP"Y8 88 88 db 88""Yb 88 dP
{Fore.BLUE}`Ybo." 88 88__dP 88 88Yb88 dP `" {Fore.CYAN}`Ybo." 88 88 dPYb 88__dP 88odP
{Fore.BLUE}o.`Y8b 88 88"Yb 88 88 Y88 Yb "88 {Fore.CYAN}o.`Y8b 888888 dP__Yb 88"Yb 88"Yb
{Fore.BLUE}8bodP' 88 88 Yb 88 88 Y8 YboodP {Fore.CYAN}8bodP' 88 88 dP""""Yb 88 Yb 88 Yb {Style.RESET_ALL}
'''
help_message = f"""
Usage: sshark {Fore.CYAN}<MODE> {Fore.BLUE}<KEYWORD> {Fore.MAGENTA}<OPTIONAL ARGUMENT>{Style.RESET_ALL}
Description:
A powerful search and replace tool for scanning through files in a directory.
It allows you to search for keywords in files with different match modes and
optionally replace them. It also supports searching through specific paths.
Modes:
{Fore.CYAN}
-md{Style.RESET_ALL} Match mode: default (case-insensitive, partial match).
Example: Finds keywords in any case (e.g. "hello" matches "Hello", "HELLO").
{Fore.CYAN}
-mc{Style.RESET_ALL} Match mode: case-sensitive (exact match).
Example: Only matches "hello" if the keyword is exactly "hello".
{Fore.CYAN}
-mw{Style.RESET_ALL} Match mode: whole word (case-insensitive).
Example: Matches "hello" as a whole word (e.g. "hello" matches "hello", but not "hellos").
{Fore.CYAN}
-me{Style.RESET_ALL} Match mode: case-sensitive and whole word.
Example: Finds only the exact match of "hello" as a whole word.
Optional Arguments:
{Fore.MAGENTA}
-r {Fore.GREEN}"replace_value"{Style.RESET_ALL} Replace the found keyword with the given "replace_value".
Example: Use this to replace all instances of the keyword with a new string.
{Fore.MAGENTA}
-p {Fore.GREEN}"path"{Style.RESET_ALL} The directory path where the search will be performed.
Defaults to the current directory if not provided.
Examples:
sshark {Fore.CYAN}-md {Fore.BLUE}"foo"{Style.RESET_ALL} # Search for "foo" (case-insensitive)
sshark {Fore.CYAN}-mc {Fore.BLUE}"foo"{Style.RESET_ALL} # Search for "foo" (case-sensitive)
sshark {Fore.CYAN}-mw {Fore.BLUE}"foo" {Fore.MAGENTA}-r {Fore.GREEN}"bar"{Style.RESET_ALL} # Replace "foo" with "bar" (whole word, case-insensitive)
sshark {Fore.CYAN}-me {Fore.BLUE}"foo" {Fore.MAGENTA}-p {Fore.GREEN}"/path/to/dir"{Style.RESET_ALL} # Search for "foo" exactly (case-sensitive and whole word) in a specific directory
"""
print(logo)
print(help_message)
def main():
# Check if enough arguments are provided
if len(sys.argv) < 2:
print_help()
sys.exit(1)
# Default search path is the current directory
search_path = os.getcwd()
# Extract the match mode and keyword
if sys.argv[1] in ['-md', '-mc', '-mw', '-me']:
match_mode = sys.argv[1]
keyword = sys.argv[2]
else:
match_mode = '-md' # Default match mode if no argument is provided
keyword = sys.argv[1]
# Check if the replace option is given
replace = None
if "-r" in sys.argv:
replace_index = sys.argv.index("-r")
replace = sys.argv[replace_index + 1]
# Check if the path argument is given
if "-p" in sys.argv:
path_index = sys.argv.index("-p")
search_path = sys.argv[path_index + 1]
# Call the search and replace function
search_and_replace(keyword, match_mode, search_path, replace)
if __name__ == "__main__":
main()