You are not logged in.

#1 2010-09-26 05:32:02

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,424
Website

[Solved] Simple note taking function in bash

I found this simple note taking function a couple of weeks ago, and it does pretty much exactly what I need:

n() { $EDITOR ~/.notes/"$*".txt ;}
nls() { ls -c ~/.notes | grep "$*" ;}

The one deficiency is that the second line doesn't work for anything other than the top-level directory (.notes). So, to display sub-directories, I hacked it to get this:

nls() { tree -CF --noreport ~/.notes | awk '{print $4,$5}' | tr -d [:digit:] | sed 's/]//' | cut -d"." -f1 ; }

Yes, I know it is ugly - but it works: it outputs like this:

$ nls
 
file a
file b
file c
directory a/
  file a1
  file a2

... which is the outcome I was looking for.


What I would like help with is:

a) Suggestions about how to make it more efficient (please don't just rewrite it, rather point me at areas I should investigate so I can learn)

b) At what point does something like this move from a function in .bashrc to it's own script?

Last edited by jasonwryan (2010-09-27 05:45:30)


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

#2 2010-09-26 07:36:01

livibetter
Member
From: Taipei
Registered: 2008-05-14
Posts: 95
Website

Re: [Solved] Simple note taking function in bash

$ nls() { find ~/.notes -printf '\033[%dG%f\n' | tail -n +2 ; }
$ nls
c
a
dira
 a2
 a1
b

Use depth '%d' and ANSI escape code to set cursor position.

The output is not as clear as yours, not in alphabetical order and no tailing '/' for directory, but it uses less commands.

Offline

#3 2010-09-26 10:36:52

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: [Solved] Simple note taking function in bash

'ls -Rc' ?

nls() { ls -Rc ~/.notes | grep "$*" ;}

Doesn't show the dir structure thought.

This

find <where> -iname "*<what>*"

shows the paths. Now just add the time-sorting part ;P
How did you search for "foo" or "bar" or "baz" with the second command?

Am I totally missing the point?

Edit:

find <where> -iname "*<what>*.txt" | nl

You are shown the numbered list and you pick _one_ file for editing:

$EDITOR $(find <where> -iname "*<what>*.txt" | sed -n "$1"p)

Last edited by karol (2010-09-26 11:27:02)

Offline

#4 2010-09-26 12:18:39

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: [Solved] Simple note taking function in bash

jasonwryan wrote:

What I would like help with is:

a) Suggestions about how to make it more efficient (please don't just rewrite it, rather point me at areas I should investigate so I can learn)

If you'd like to continue using tree, read up on awk. I believe the entire pipeline could be soaked up into a single awk script. Find is also an excellent utility to do this with. Whatever you do, don't involve ls.

jasonwryan wrote:

b) At what point does something like this move from a function in .bashrc to it's own script?

My train of thought is something like this:

1) If it's short and doesn't take arguments, its an alias (and this could be an alias in its current form).
2) If it's long enough that readability is greatly improved with newlines and indenting, then its a function.
3) If I have to start doing things like option parsing and validation or it's going to be more than about 20 lines, out to goes to its own file.

Offline

#5 2010-09-26 12:28:56

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: [Solved] Simple note taking function in bash

Also, try this https://bbs.archlinux.org/viewtopic.php?pid=763498 by user gaudencio

fns() {
 export IFS=:
 select X in `find ./ -iname "*$1*" -printf %p\: `
 do
   echo "enter command to run on $X"
   read commandtodo
   $commandtodo $X
   break
 done
 unset IFS
}

You can simplify it if you intend to always run the same app, e.g. $EDITOR.

Offline

#6 2010-09-26 19:58:16

skanky
Member
From: WAIS
Registered: 2009-10-23
Posts: 1,847

Re: [Solved] Simple note taking function in bash

falconindy wrote:
jasonwryan wrote:

What I would like help with is:

a) Suggestions about how to make it more efficient (please don't just rewrite it, rather point me at areas I should investigate so I can learn)

If you'd like to continue using tree, read up on awk. I believe the entire pipeline could be soaked up into a single awk script. Find is also an excellent utility to do this with. Whatever you do, don't involve ls.

I agree. If you're using awk, then it can do everything that sed and tr are doing in that pipe. It's something I see a lot - and in most cases isn't an issue really, but I find it a mild irritation (and I fully admit that it's not justified). awk if very powerful, and you can easily manipulate multi-line notes (for example) with it, as well as just search for the files.

falconindy wrote:
jasonwryan wrote:

b) At what point does something like this move from a function in .bashrc to it's own script?

My train of thought is something like this:

1) If it's short and doesn't take arguments, its an alias (and this could be an alias in its current form).
2) If it's long enough that readability is greatly improved with newlines and indenting, then its a function.
3) If I have to start doing things like option parsing and validation or it's going to be more than about 20 lines, out to goes to its own file.


Again agree. However, I don't bother doing aliases any more (the BASH manual basically says that for most purposes functions supercede aliases).
I'll also bend the limits of what's to what if (a) I use something a lot, it may stay as a function or (b) it gets used in a lot of other functions/scripts it may stay as a function or (c) it needs to be a script for some reason eg used in non-interactive shells, etc.

But yeah, as said above, find is probably the best thing to use for this.


"...one cannot be angry when one looks at a penguin."  - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle

Offline

#7 2010-09-26 20:37:20

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,424
Website

Re: [Solved] Simple note taking function in bash

Thank you all for your suggestions.

falconindy wrote:

If you'd like to continue using tree, read up on awk. I believe the entire pipeline could be soaked up into a single awk script. Find is also an excellent utility to do this with. Whatever you do, don't involve ls.

Thanks falconindy - I'll pursue awk in the first instance. That was the sort of pointer I was looking for.

skanky and livibtetter wrote:

find is probably the best thing to use.

I played around with find, but struggled with the formatting - which is why I ended up with the whole frankenstein thing growing out of tree... (as attractive as that horribly mixed metaphor)

karol wrote:

'ls -Rc' ?

Probably after seeing it repeated countless times across these boards, I've taken falconindy's advice about ls to heart smile but the link to gaudencio's solution is a good one - thank you.


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

#8 2010-09-26 20:44:12

skanky
Member
From: WAIS
Registered: 2009-10-23
Posts: 1,847

Re: [Solved] Simple note taking function in bash

but struggled with the formatting

Yeah, should have thought of that.


"...one cannot be angry when one looks at a penguin."  - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle

Offline

#9 2010-09-27 00:58:33

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,424
Website

Re: [Solved] Simple note taking function in bash

Some progress. Just using tree and awk, I have a reasonable output (with the advantage that it is scalable if the dir structure gets any deeper):

tree -CR --noreport ~/.notes | awk '{ if (NF==1) print $1; else if (NF==2) print $2,$3; else if (NF==3) print $3 }'

Formatting isn't as pleasing, but I can work on that...

# edit added some indentation for the sub-directories and it is all good

nls() { tree -CR --noreport ~/.notes | awk '{ if (NF==1) print $1; else if (NF==2) print $2,$3; else if (NF==3) print "  "$3 }' ;}

## edit (final) - read up some more on awk and realised I could deal to the formatting in the same script == WIN. Now the whole thing prints out quite nicely

 nls() { tree -CR --noreport ~/.notes | awk '{ if ((NR > 1) gsub(/.txt/,"")); if (NF==1) print $1; else if (NF==2) print $2,$3; else if (NF==3) printf "  %s\n", $3 }' ;}

Last edited by jasonwryan (2010-09-27 05:44:56)


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

#10 2010-09-27 08:59:38

skanky
Member
From: WAIS
Registered: 2009-10-23
Posts: 1,847

Re: [Solved] Simple note taking function in bash

Check out printf.

Also:

$ echo "one two three" | awk '{printf "  ---  %s\n" $NF}'
  ---  three

"...one cannot be angry when one looks at a penguin."  - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle

Offline

#11 2010-09-27 09:27:25

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,424
Website

Re: [Solved] Simple note taking function in bash

Thanks skanky. I've got it working with printf - is this less of a hack than using plain print?


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

#12 2010-09-27 09:43:09

skanky
Member
From: WAIS
Registered: 2009-10-23
Posts: 1,847

Re: [Solved] Simple note taking function in bash

It may not be much of an improvement in this case, but it makes formatting simpler. It's generally at its most useful if you're outputting multiple variables/fields. It also allows for sprintf type formatting and the like (very useful if columnising your output). It's worth knowing about if you're looking to use awk more widely. You do need the \n though as it doesn't have one by default like print.

I *guess* that print is just a wrapper round printf to simplify basic output.


EDIT the $NF was possibly as important.

$ tree -CF --noreport ~/personal | awk '/.*\.txt$/{ print $NF }' 
homepage.txt
terms&conditions.txt

Last edited by skanky (2010-09-27 09:47:36)


"...one cannot be angry when one looks at a penguin."  - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle

Offline

#13 2010-09-27 09:46:43

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,424
Website

Re: [Solved] Simple note taking function in bash

skanky wrote:

You do need the \n though as it doesn't have one by default like print.

Heh. That did have me scratching my head for a mniute or two...


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

#14 2010-09-27 09:48:10

skanky
Member
From: WAIS
Registered: 2009-10-23
Posts: 1,847

Re: [Solved] Simple note taking function in bash

jasonwryan wrote:
skanky wrote:

You do need the \n though as it doesn't have one by default like print.

Heh. That did have me scratching my head for a mniute or two...

I still often forget it. neutral


"...one cannot be angry when one looks at a penguin."  - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle

Offline

#15 2010-09-27 09:51:37

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: [Solved] Simple note taking function in bash

jasonwryan wrote:
skanky wrote:

You do need the \n though as it doesn't have one by default like print.

Heh. That did have me scratching my head for a mniute or two...

It's more powerfull that way, you can do more tricks ;P

Offline

Board footer

Powered by FluxBB