Compare commits
	
		
			No commits in common. "d0dd2cff1750909d75e948fe513ad3a7727dd5b3" and "0d0cfac86014f0f60690884148c2d6ecb6af29e8" have entirely different histories.
		
	
	
		
			d0dd2cff17
			...
			0d0cfac860
		
	
		
							
								
								
									
										27
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								README.md
									
									
									
									
									
								
							@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for line in lines:
 | 
					 | 
				
			||||||
                n = n + 1
 | 
					 | 
				
			||||||
            # Check if case insensitive
 | 
					            # Check if case insensitive
 | 
				
			||||||
            if 'i' in options:
 | 
					            if 'i' in options:
 | 
				
			||||||
                    i_case = True
 | 
					                pattern = pattern.lower()
 | 
				
			||||||
 | 
					            for line in lines:
 | 
				
			||||||
 | 
					                n = n + 1
 | 
				
			||||||
                # 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)
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user