You are not logged in.

#1 2018-10-25 11:40:19

leslieking
Member
Registered: 2017-02-11
Posts: 5

Using grep to search in files

Hello, I take all my notes in asciidoc which is a plain-text format similar to Markdown.
The "title of the document" is on line 1 in every document and it starts with an equal sign, followed by the document title:

= Document title

So, If I have 100 files and I want to search through document titles I use:

grep '^=.*some words'

It's pretty cool. However I would like to add more granularity. All my asciidoc files contain:

= Document title
:keywords: linux, tutorial, postgresql, etc

Is it possible to use grep to retrieve document titles (just as I did above) but only if the document contains a specific keyword in :keywords:? The line that contains the keywords always starts with :keywords: which signals its purpose.
In other words: Show document tiles that contain the words ...... and contain one of the keywords ..... in :keywords:

Any suggestion appreciated!

Last edited by leslieking (2018-10-25 11:43:19)

Offline

#2 2018-10-25 12:41:12

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,522
Website

Re: Using grep to search in files

I'd use sed:

sed -ns '1{/^=/{s/^= //;h;n;s/^:keywords:.*needle//;t match;b end;:match;x;p;:end;q;};}' /path/to/notes/*

Note this assumes the title is always on line 1 (if present) and the keywords are always on line 2 (if present).

This can be easily modified to loosen those assumptions - but if they hold it is far more efficient to just check the first two lines rather than scanning the entirity of each file.

The sed script is a bit ugly on one line, but here it is expanded and commented:

# Only check the first line
1 {
	# And only if it starts with an equals sign
	/^=/ {
		# Trim the '= ' from the start of the line
		s/^= //
		# Move the title to the hold buffer
		h
		# Get the next (second) line
		n
		# Check for 'needle' in the keywords, branch to 'match' if found
		s/^:keywords:.*needle//
		t match
		# Otherwise branch to end to quit
		b end
		# If matched, retrieve the title from the hold buffer and print it
		:match
		x
		p
		# Unconitionally stop after reading the first two lines
		:end
		q
	}
}

And here in a shell function that takes the search term(s) as parameters:

match_note() {
   sed -ns '1{/^=/{s/^= //;h;n;s/^:keywords:.*'"$@"'//;t match;b end;:match;x;p;:end;q;};}'  /path/to/notes/*
}

"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3 2018-10-25 15:07:43

YCH
Member
Registered: 2014-01-28
Posts: 53

Re: Using grep to search in files

grep -rlZ '^:keyword:.*KEYWORD' /search_path |
xargs -0 grep '^=.*TITLE'

find list of files that match keywords then grepping title.

grep :
-r recursive
-l only print file names
-Z null as delimiter

xargs :
-0 null as delimiter


YCH

Offline

#4 2018-10-25 15:30:53

leslieking
Member
Registered: 2017-02-11
Posts: 5

Re: Using grep to search in files

Thank you. I appreciate your time. The sed example is great, however I prefer "grep" because I can fire it directly from Vim by using the Vim-grepper plugin and populates the results at the bottom.
The grep example posted by YCH works however don't understand why I get that ".: Is a directory" thing as a result as well.

https://i.imgur.com/Zn1BBu0.png

Mod Edit - Replaced oversized image with link.
CoC - Pasting pictures and code

Last edited by Slithery (2018-10-25 15:39:36)

Offline

#5 2018-10-25 17:38:54

YCH
Member
Registered: 2014-01-28
Posts: 53

Re: Using grep to search in files

leslieking wrote:

Thank you. I appreciate your time. The sed example is great, however I prefer "grep" because I can fire it directly from Vim by using the Vim-grepper plugin and populates the results at the bottom.
The grep example posted by YCH works however don't understand why I get that ".: Is a directory" thing as a result as well.

https://i.imgur.com/Zn1BBu0.png

Mod Edit - Replaced oversized image with link.
CoC - Pasting pictures and code

try -r

grep man page said,

If no FILE is given, recursive searches examine the working directory

but when I did `grep pattern`, it did nothing. Looks like just wait something from stdin. So we need `-r`.

Or try `--directories=skip`

Last edited by YCH (2018-10-25 17:45:29)


YCH

Offline

Board footer

Powered by FluxBB