Compare commits

..

No commits in common. "d0dd2cff1750909d75e948fe513ad3a7727dd5b3" and "0d0cfac86014f0f60690884148c2d6ecb6af29e8" have entirely different histories.

3 changed files with 36 additions and 31 deletions

View File

@ -6,31 +6,30 @@ Then this is for you...
## What is this? ## What is this?
`crapgrep` is a poor imitation of the Unix utility `grep`, written in Python. `crapgrep` is a poor imitation of the Unix utility `grep` written in Python.
More specifically, it's a command line tool to search for a pattern or a substring in each line of one or more text files. More specifically, it's a command line tool to search for a pattern or a substring in each line of one or more text files.
The command synopsis is very similar to `grep`'s, although it needs the Python interpreter to be invoked explicitly (at the moment, at least): The command synopsis is very similar to `grep`, although it needs the Python interpreter to be invoked explicitly (at the moment, at least):
``` ```
python crapgrep.py [OPTION...] [PATTERN] [FILE...] python crapgrep.py [OPTIONS] [PATTERN] [FILE[...]]
``` ```
> _**Note**: obviously, `crapgrep` doesn't read from `stdin`, which makes it even more useless..._ _**Note**: obviously, `crapgrep` doesn't read from `stdin`, which makes it even more useless..._
## Installation ## Installation
If you like wasting time (because apparently you have nothing better to do), you can try `crapgrep` by cloning the repository with `git`: If you like wasting time because apparently you have nothing better to do, you can try `crapgrep` by cloning the repository with `git`:
```bash ```bash
git clone https://baltig.cnr.it/nicolo.paraciani/crapgrep.git git clone https://baltig.cnr.it//nicolo.paraciani//crapgrep.git
``` ```
then then
```bash ```bash
cd crapgrep/crapgrep cd crapgrep
python crapgrep.py <options> <files> python crapgrep.py <option> <file(s)>
``` ```
## Examples ## Examples
@ -45,15 +44,15 @@ Searching for the simple string `'hola'` in file `garbage.txt` in the current di
python crapgrep.py hola garbage.txt python crapgrep.py hola garbage.txt
``` ```
To make the search case-insensitive: To make the search case-insensitive, you could do:
``` ```
python crapgrep.py -i hola garbage.txt python crapgrep.py -i hOlA garbage.txt
``` ```
### Regexp ### Regexp
_**Note**: unlike `grep`, `crapgrep` doesn't treat the pattern as a regular expression by default, it must be specified by passing the `-E` option explicitly._ _**Note**: unlike `grep`, `crapgrep` doesn't treat the string as a regular expression pattern by default, it must be specified by passing the `-E` option explicitly._
Searching for pattern `'^urka[0-9]'` in files `garbage1.txt` and `garbage2.txt` in the parent directory: Searching for pattern `'^urka[0-9]'` in files `garbage1.txt` and `garbage2.txt` in the parent directory:
@ -97,9 +96,7 @@ If you're asking yourself:
> _Why would you inflict something like this upon the world?_ > _Why would you inflict something like this upon the world?_
the answer is... the answer is... _because it's fun!_
> _because it's fun!_
## TODO ## TODO

View File

@ -2,9 +2,11 @@ import exceptions
import re import re
import os import os
import sys import sys
import sty
def find_line(line: str, pattern: str, i_case: bool, is_regexp=False) -> bool: # TODO Avoid extra fname argument??
def find_line(line: str, pattern: str, is_regexp=False) -> bool:
""" """
Distinguish between regexp or not (default is False) Distinguish between regexp or not (default is False)
""" """
@ -14,9 +16,6 @@ def find_line(line: str, pattern: str, i_case: bool, is_regexp=False) -> bool:
if is_regexp: if is_regexp:
matches = re.findall(pattern, line) matches = re.findall(pattern, line)
FIND_COND = len(matches) > 0 FIND_COND = len(matches) > 0
elif i_case:
lower = line.lower()
FIND_COND = lower.find(pattern.lower()) != -1
else: else:
FIND_COND = line.find(pattern) != -1 FIND_COND = line.find(pattern) != -1
@ -94,7 +93,7 @@ def parse_args(args: list) -> dict:
# TODO does it make sense? # TODO does it make sense?
for opt in options: for opt in options:
if opt not in OPTS: if opt not in OPTS:
raise exceptions.InvalidOptionError(opt) raise exceptions.InvalidOption(opt[1:])
args_tree["options"] = options args_tree["options"] = options
@ -114,13 +113,22 @@ def parse_args(args: list) -> dict:
return args_tree return args_tree
def match_regexp(pattern: str, line: str) -> object:
"""
Search for pattern in the given line and return
a match object or None if no match found.
Flags??
"""
return re.search(pattern, line)
def process_grep(args_tree: dict) -> list: def process_grep(args_tree: dict) -> list:
lines = [] lines = []
found_lines = [] found_lines = []
options = args_tree["options"] options = args_tree["options"]
pattern = args_tree["pattern"] pattern = args_tree["pattern"]
files = args_tree["files"] files = args_tree["files"]
i_case = False
try: try:
for f in files: for f in files:
@ -131,19 +139,19 @@ def process_grep(args_tree: dict) -> list:
n = 0 n = 0
# Check if case insensitive
if 'i' in options:
pattern = pattern.lower()
for line in lines: for line in lines:
n = n + 1 n = n + 1
# Check if case insensitive
if 'i' in options:
i_case = True
# Check if regexp flag # Check if regexp flag
if 'E' in options: if 'E' in options:
# pattern is regexp # pattern is regexp
if not check_pattern(pattern): if not check_pattern(pattern):
raise exceptions.InvalidPatternError(pattern) raise exceptions.InvalidPattern(pattern)
found = find_line(line, pattern, i_case, True) found = find_line(line, pattern, True)
else: else:
found = find_line(line, pattern, i_case) found = find_line(line, pattern)
lnum = str(n) + ':' if 'n' in options else '' lnum = str(n) + ':' if 'n' in options else ''
@ -167,7 +175,7 @@ if __name__ == "__main__":
try: try:
args_tree = parse_args(args) args_tree = parse_args(args)
except exceptions.InvalidOptionError as e: except exceptions.InvalidOption as e:
print(e.get_message()) print(e.get_message())
print_usage() print_usage()
sys.exit(1) sys.exit(1)
@ -175,6 +183,6 @@ if __name__ == "__main__":
try: try:
for line in process_grep(args_tree): for line in process_grep(args_tree):
print(line) print(line)
except exceptions.InvalidPatternError as e: except exceptions.InvalidPattern as e:
print(e.get_message()) print(e.get_message())
sys.exit(1) sys.exit(1)

View File

@ -1,4 +1,4 @@
class InvalidOptionError(Exception): class InvalidOption(Exception):
def __init__(self, invalid_opt): def __init__(self, invalid_opt):
self.invalid_opt = invalid_opt self.invalid_opt = invalid_opt
@ -6,7 +6,7 @@ class InvalidOptionError(Exception):
return f"crapgrep: invalid option -- '{self.invalid_opt}'" return f"crapgrep: invalid option -- '{self.invalid_opt}'"
class InvalidPatternError(Exception): class InvalidPattern(Exception):
def __init__(self, pattern): def __init__(self, pattern):
self.invalid = pattern self.invalid = pattern