Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ Call scnnr with the `-h` flag:

```
$ scnnr -h
-c OPTIONAL Scnnr MODE
show line and column numbers for each match (requires -k)
when enabled, finds ALL matches in files (no early exit)
-d string
OPTIONAL Scnnr MODE and OPTIONAL FingerrintFinder MODE
directory where scnnr will scan
Expand All @@ -63,6 +66,9 @@ $ scnnr -h
if no keywords are given - all file paths of given file extensions will be returned
if keywords are given - only filepaths of matches will be returned
FingerprintFinder: this is a comma delimited list of SHA2-256 hashes to find files by
-l OPTIONAL Scnnr MODE
show line numbers for each match (requires -k)
when enabled, finds ALL matches in files (no early exit)
-m string
OPTIONAL
mode that scnnr will run in
Expand Down Expand Up @@ -137,6 +143,50 @@ README.md
cmd/scanner.go
```

### Keywords with line numbers

```bash
$ scnnr -d . -e .md,.go -k fileData,cache -l
scnnr_bins/README.md:117:cache
scnnr_bins/README.md:122:cache
scnnr_bins/README.md:129:cache
scnnr_bins/README.md:135:fileData
scnnr_bins/README.md:135:cache
README.md:123:cache
README.md:128:cache
README.md:135:cache
README.md:141:fileData
README.md:141:cache
scnnr_bins/README.md:377:cache
scnnr_bins/README.md:387:cache
README.md:383:cache
README.md:393:cache
pkg/scanner.go:215:fileData
pkg/scanner.go:222:fileData
```

### Keywords with both line numbers and column numbers

```bash
$ scnnr -d . -e .md,.go -k fileData,cache -c
scnnr_bins/README.md:117:53:cache
scnnr_bins/README.md:122:29:cache
scnnr_bins/README.md:129:22:cache
scnnr_bins/README.md:135:28:fileData
scnnr_bins/README.md:135:37:cache
scnnr_bins/README.md:377:36:cache
scnnr_bins/README.md:387:40:cache
pkg/scanner.go:215:9:fileData
pkg/scanner.go:222:26:fileData
README.md:123:53:cache
README.md:128:29:cache
README.md:135:22:cache
README.md:141:28:fileData
README.md:141:37:cache
README.md:383:36:cache
README.md:393:40:cache
```

# File Name Finder (NameFinder) (fnf)

```
Expand Down
25 changes: 21 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ func main() {
truthy values are: 1, t, T, true, True, TRUE
falsy values are: 0, f, F, false, False, FALSE`)

var showLines bool
flag.BoolVar(&showLines, "l", false, `OPTIONAL Scnnr MODE
show line numbers for each match (requires -k)
when enabled, finds ALL matches in files (no early exit)`)

var showCols bool
flag.BoolVar(&showCols, "c", false, `OPTIONAL Scnnr MODE
show line and column numbers for each match (requires -k)
when enabled, finds ALL matches in files (no early exit)`)

var paths string
flag.StringVar(&paths, "p", "", `REQUIRED NameFinder MODE
any absolute path - can be comma delimited: Example: $HOME or '/tmp,/usr'`)
Expand All @@ -95,7 +105,8 @@ func main() {

directory = dir

if mode == "fnf" {
switch mode {
case "fnf":
scanFuzzy := strings.Split(fuzzy, ",")
scanPaths := strings.Split(paths, ",")

Expand All @@ -108,31 +119,37 @@ func main() {
for _, file := range nfnf.Files {
fmt.Println(file)
}
} else if mode == "scn" {
case "scn":
extensions = strings.Split(ext, ",")
keywords = strings.Split(kwd, ",")

if (showLines || showCols) && keywords[0] == "" {
log.Fatal("Position tracking flags (-l, -c) require keywords (-k)")
}

scanner := scnnr.Scanner{
Regex: rgx,
Keywords: keywords,
Directory: directory,
FileExtensions: extensions,
ShowLines: showLines,
ShowCols: showCols,
}

err := scanner.Scan()

if err != nil {
log.Fatal(err)
}
} else if mode == "fsf" {
case "fsf":
nfsf := scnnr.NewFileSizeFinder(size)

nfsf.Scan(directory)

for _, file := range nfsf.Files {
fmt.Println(file)
}
} else if mode == "fff" {
case "fff":
keywords = strings.Split(kwd, ",")

if keywords[0] == "" {
Expand Down
91 changes: 75 additions & 16 deletions pkg/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ import (
type Scanner struct {
sync.Mutex
Regex bool
ShowLines bool
ShowCols bool
Directory string
FileExtensions []string
Keywords []string
KeywordMatches []string
AllMatches []Match
MatchedFilePaths []FileData
}

Expand All @@ -28,6 +31,14 @@ type FileData struct {
Info os.FileInfo
}

// Match represents a single keyword match with position information
type Match struct {
Path string
Line int
Column int
Keyword string
}

// Scan walks the given directory tree and stores all matching files into a slice
func (s *Scanner) Scan() error {
err := filepath.Walk(s.Directory, s.scan)
Expand Down Expand Up @@ -61,13 +72,41 @@ func (s *Scanner) Scan() error {

wg.Wait()
}
}

fmt.Println(strings.Join(s.KeywordMatches, "\n"))
// Output results based on position tracking settings
if s.ShowLines || s.ShowCols {
s.outputPositionMatches()
} else {
// Original behavior
fmt.Println(strings.Join(s.KeywordMatches, "\n"))
}
}

return nil
}

// outputPositionMatches formats and outputs matches with position information
func (s *Scanner) outputPositionMatches() {
for _, match := range s.AllMatches {
output := match.Path

if s.ShowCols {
// -c flag shows both line and column
output = fmt.Sprintf("%s:%d:%d", output, match.Line, match.Column)
} else if s.ShowLines {
// -l flag shows only line
output = fmt.Sprintf("%s:%d", output, match.Line)
}

// If multiple keywords, append the matching keyword
if len(s.Keywords) > 1 {
output = fmt.Sprintf("%s:%s", output, match.Keyword)
}

fmt.Println(output)
}
}

func (s *Scanner) scan(path string, info os.FileInfo, err error) error {
if err != nil {
return err
Expand Down Expand Up @@ -106,38 +145,58 @@ func (s *Scanner) parse(match FileData) {

found := false

lineNumber := 0

positionTracking := s.ShowLines || s.ShowCols

for scanner.Scan() {
line := scanner.Text()

lineNumber++

for i := 0; i < len(s.Keywords); i++ {
if found {
if !positionTracking && found {
break
}

matchFound := false
var column int

if s.Regex {
re := regexp.MustCompile(s.Keywords[i])

if re.Match([]byte(line)) {
s.Lock()

s.KeywordMatches = append(s.KeywordMatches, match.Path)

found = true

s.Unlock()

break
if loc := re.FindStringIndex(line); loc != nil {
matchFound = true
column = loc[0] + 1
}
} else {
if strings.Contains(line, s.Keywords[i]) {
s.Lock()
if idx := strings.Index(line, s.Keywords[i]); idx != -1 {
matchFound = true
column = idx + 1
}
}

if matchFound {
s.Lock()

if positionTracking {
match := Match{
Path: match.Path,
Line: lineNumber,
Column: column,
Keyword: s.Keywords[i],
}

s.AllMatches = append(s.AllMatches, match)
} else {
s.KeywordMatches = append(s.KeywordMatches, match.Path)

found = true
}

s.Unlock()
s.Unlock()

if !positionTracking {
break
}
}
Expand Down
16 changes: 16 additions & 0 deletions scripts/e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,19 @@ echo "--- FILE FINGERPRINT FINDER DRY RUN: BEGIN---"
go run main.go -m fff -k $(go run cmd/checksum/main.go) -d .

echo "--- FILE FINGERPRINT FINDER DRY RUN: DONE---"

sleep 2

echo "--- SCANNER LINE RUN: BEGIN---"

go run main.go -k main,const,let,var,for -p $HOME -l

echo "--- SCANNER LINE RUN: DONE ---"

sleep 2

echo "--- SCANNER LINE AND COL RUN: BEGIN---"

go run main.go -k main,const,let,var,for -p $HOME -c

echo "--- SCANNER LINE AND COL RUN: DONE ---"