You are not logged in.
Pages: 1
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
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
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
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
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
Pages: 1