Skip to content

Commit d8774a9

Browse files
Add Terminal File Search script for issue sumanth-0#788
Implements a comprehensive terminal file search tool with features: - Search by file name pattern (wildcards supported) - Search by file extension - Filter by file type (file/directory) - Filter by file size (min/max) - Recursive search option - Verbose output with file details - Results limit option Resolves sumanth-0#788
1 parent b7fb013 commit d8774a9

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Terminal File Search
4+
A powerful command-line tool for searching files with various filters.
5+
"""
6+
7+
import os
8+
import sys
9+
import argparse
10+
from pathlib import Path
11+
import fnmatch
12+
from datetime import datetime
13+
14+
15+
def format_size(size):
16+
"""Format file size in human-readable format."""
17+
for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
18+
if size < 1024.0:
19+
return f"{size:.2f} {unit}"
20+
size /= 1024.0
21+
return f"{size:.2f} PB"
22+
23+
24+
def format_time(timestamp):
25+
"""Format timestamp to readable date."""
26+
return datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
27+
28+
29+
def matches_criteria(file_path, args):
30+
"""Check if file matches all search criteria."""
31+
try:
32+
stat = file_path.stat()
33+
34+
# Check name pattern
35+
if args.name and not fnmatch.fnmatch(file_path.name, args.name):
36+
return False
37+
38+
# Check extension
39+
if args.ext and not file_path.suffix.lower() == f".{args.ext.lower()}":
40+
return False
41+
42+
# Check minimum size
43+
if args.min_size and stat.st_size < args.min_size * 1024:
44+
return False
45+
46+
# Check maximum size
47+
if args.max_size and stat.st_size > args.max_size * 1024:
48+
return False
49+
50+
# Check file type
51+
if args.type:
52+
if args.type == 'f' and not file_path.is_file():
53+
return False
54+
if args.type == 'd' and not file_path.is_dir():
55+
return False
56+
57+
return True
58+
except (OSError, PermissionError):
59+
return False
60+
61+
62+
def search_files(directory, args):
63+
"""Search files in directory based on criteria."""
64+
results = []
65+
try:
66+
path = Path(directory).resolve()
67+
68+
for item in path.rglob('*') if args.recursive else path.glob('*'):
69+
if matches_criteria(item, args):
70+
results.append(item)
71+
72+
if args.limit and len(results) >= args.limit:
73+
break
74+
except PermissionError:
75+
print(f"Permission denied: {directory}", file=sys.stderr)
76+
77+
return results
78+
79+
80+
def display_results(results, args):
81+
"""Display search results."""
82+
if not results:
83+
print("No files found matching the criteria.")
84+
return
85+
86+
print(f"\nFound {len(results)} file(s):\n")
87+
88+
for file_path in sorted(results):
89+
if args.verbose:
90+
try:
91+
stat = file_path.stat()
92+
size = format_size(stat.st_size)
93+
mtime = format_time(stat.st_mtime)
94+
print(f"{file_path} | Size: {size} | Modified: {mtime}")
95+
except OSError:
96+
print(file_path)
97+
else:
98+
print(file_path)
99+
100+
101+
def main():
102+
parser = argparse.ArgumentParser(
103+
description="Search files in terminal with various filters"
104+
)
105+
parser.add_argument('directory', nargs='?', default='.', help='Directory to search (default: current)')
106+
parser.add_argument('-n', '--name', help='File name pattern (supports wildcards)')
107+
parser.add_argument('-e', '--ext', help='File extension (without dot)')
108+
parser.add_argument('-t', '--type', choices=['f', 'd'], help='Type: f=file, d=directory')
109+
parser.add_argument('--min-size', type=int, help='Minimum file size in KB')
110+
parser.add_argument('--max-size', type=int, help='Maximum file size in KB')
111+
parser.add_argument('-r', '--recursive', action='store_true', help='Search recursively')
112+
parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output with details')
113+
parser.add_argument('-l', '--limit', type=int, help='Limit number of results')
114+
115+
args = parser.parse_args()
116+
117+
results = search_files(args.directory, args)
118+
display_results(results, args)
119+
120+
121+
if __name__ == "__main__":
122+
main()

0 commit comments

Comments
 (0)