You are not logged in.

#1 2010-05-23 14:24:52

gaudencio
Member
Registered: 2009-03-30
Posts: 33

VERY simple find and execute script to be improved

hello, I've been searching for other scripts like the following but have found nothing, so decided to hack this together. I have almost 0 bash programming experience, so I'm sure some kind soul could easily improve it. The functionality should be obvious to anyone here. It could probably do with some limit to the files being searched for, but I only use it in directories and with queries that I know won't give lots of results. Obviously, if there's some better script/option that my google fu couldn't find, then please let me know. Smart arse one liners more than welcome.

#!/bin/bash
finder=`find ./ -iname "*$1*" -printf %p\:`
IFS=:
select filename in $finder
do
  echo "enter command to run on $filename"
  read commandtodo
  $commandtodo $filename
  break
done
unset IFS

Offline

#2 2010-05-23 15:03:16

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

Re: VERY simple find and execute script to be improved

I use

search () { find "./" \! -name "*~" -type f -exec grep -isI "$1" {} \; -print; }

for searching inside my documents in my ~/docs folder.
Instead of grep maybe you could use your 'commandtodo'.
Your script is interactive, mine isn't - I like mine better :-)

Offline

#3 2010-05-23 15:21:15

gaudencio
Member
Registered: 2009-03-30
Posts: 33

Re: VERY simple find and execute script to be improved

hmm, from what I can see, yours is grepping inside all files, which is rather different than what I was going for with mine - unless I'm misunderstanding your script. Mine is interactive because it allows me to select which of the "found" files I want to execute, then put in a command to run

Offline

#4 2010-05-23 15:38:57

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

Re: VERY simple find and execute script to be improved

I don't know what commands do you intend to run - things like (re)move can be easily run from a simple one-liner

[karol@black ddelta]$ rm *.xz
rm: remove regular file `kernel26-2.6.33.3-1-i686.pkg.tar.xz'?

yes / no.

If you need a file-by-file granularity your script is OK. I try to select a bunch of files (ten biggest, files that changed yesterday etc.) and run a couple commands on them.

Can you give an example what commands and what files do you work with?

Offline

#5 2010-05-23 17:33:30

gaudencio
Member
Registered: 2009-03-30
Posts: 33

Re: VERY simple find and execute script to be improved

Ahh, apologies. I didn't explain what my script was doing because it felt somewhat patronising to explain such a simple script - but what I should have explained is what I *intended* the script to do. If you don't know what it's supposed to do, how can you improve it? My fault.
So then, basically the intention was pretty much what I wrote. Lets say I'm in my documents directory, and I know somwhere in there there's a pdf document I want about...I don't know....milk let's say. I just run "fnl milk" (the bash alias) I get a list of files with the word milk in the title, I pick the one I want, type apvlv and hey presto. It simply saves me having to do a find, then remember the address and retype that into the command line. Obviously, I can't use the exec command of find, because it might find multiple documents, and I'm only after one.

Perhaps many of you simply don't search for files this way, but for someone who grew up with the windows way of searching then rightclicking "open with", it's actually kind of a helpful little script. Of course, it could be improved enormously by two additions I can think of right now: 1 - allowing variables/wildcards to be passed 2:get it to work with standard commands (i.e. cp, cd, mv, all those things)

I hope this has explained a little better what I was going for - a tool to work "backwards" on the command line

Offline

#6 2010-05-23 18:34:13

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

Re: VERY simple find and execute script to be improved

> Ahh, apologies.
No need to apologize, I just wanted to make sure I'm not missing sth. Your script is fine, we just work a bit differently. I have one other idea for someone who doesn't like typing:

fa () {
for i in *$1*; do
     apvlv "$i"
done; }

'fa' means find and open in apvlv. It's as simple as it gets ... if you don't mind getting 3 wrong pdfs + the one you need but you can always kill the script.
You can create a bunch of such scripts where 'fX' means open in application X, but your script also gets the work done.

In fact I "borrowed" it and I'm gonna keep it in my handy scripts folder - thanks, gaudencio!

Offline

#7 2010-05-23 19:30:58

demian
Member
From: Frankfurt, Germany
Registered: 2009-05-06
Posts: 709

Re: VERY simple find and execute script to be improved

I can't help you improve it but in this thread someone posted a findopen() function and there there are some other examples for find (but not open) files.


no place like /home
github

Offline

#8 2010-05-23 19:39:26

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

Re: VERY simple find and execute script to be improved

LOL! I posted in that thread too :-)
I think using zsh is overkill and that OP's script is really nice and simple.

Offline

#9 2010-05-23 23:15:33

gaudencio
Member
Registered: 2009-03-30
Posts: 33

Re: VERY simple find and execute script to be improved

actually a much better way to do it would be to pass the selected filename to an environment variable, so you could then do whatever you wanted on it, rather than just running a single command. Unfortunately, turns out you can't pass variables back to the parent shell, which is a real bitch.

If anyone has a solution let me know.

Offline

#10 2010-05-23 23:27:52

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

Re: VERY simple find and execute script to be improved

> If anyone has a solution let me know.
Do you mean

export ABCD="/home/karol/test/alp-ch10-security.pdf"
apvlv $ABCD

Update:

[karol@black test]$ locate security.pdf > test1 && nl test1
     1  /home/karol/attic/theory/AdvancedLinuxProgramming/alp-ch10-security.pdf
     2  /home/karol/test/alp-ch10-security.pdf
aaa () {
export ABCD="$(sed -n "$1"p test1)"
}

'test1' is a file where we store our searches. You can make it a tempfile if you like. Likewise, you can unset the env var at some point.
'nl' is a command to print line numbers, 'sed -n "$1"p test1' prints the line number $1 from test1.

Feel free to parametrize it to your heart's content.

Last edited by karol (2010-05-24 00:00:52)

Offline

#11 2010-05-24 00:11:33

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: VERY simple find and execute script to be improved

Try something like this, it's a bit crazy though, but if you want to do further things with the file, then it is easily accessible with readline keys like "ALT+."

function sedsel() {
  files=$(find -iname "*$1*" | sort | cat -n)
  echo "$files"
  read -p "SELECT: "
  choice=$(echo "$files" | sed -n "${REPLY}{s/^[^\t]*\t//;s/'/'\\\\''/;s/.*/'&' /p}") && {
    xdotool type --clearmodifiers --delay 1 " $choice"
    xdotool key --clearmodifiers Home
    echo -ne '\e2K\r'
  }
}

The sed command gets the filename of the one item you chose (in this case a range works too, or $ for last line, and /.txt/ and so forth) and puts quotes around it, then xdotool types it to the next bash line, and puts the cursor at the beginning.

EDIT: added \\ to escape '

Last edited by Procyon (2010-05-24 00:40:45)

Offline

#12 2010-05-24 00:22:10

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

Re: VERY simple find and execute script to be improved

> Try something like this, it's a bit crazy though
Apart from the sed incantation I don't see anything crazy here ;-)

> it is easily accessible with readline keys like "ALT+."
Mind clarifying that bit? I press 'Alt+.' and nothing happens - is it because I have 'set -o vi' ?

Offline

#13 2010-05-24 00:27:35

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: VERY simple find and execute script to be improved

> Apart from the sed incantation I don't see anything crazy here ;-)
Using xdotool like this is though, right?

>> it is easily accessible with readline keys like "ALT+."
> Mind clarifying that bit? I press 'Alt+.' and nothing happens - is it because I have 'set -o vi' ?
Yeah, "yank-last-arg" is not in the vi keybindings.

Offline

#14 2010-05-24 00:34:43

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

Re: VERY simple find and execute script to be improved

> Using xdotool like this is though, right?
Nah :-)

> Yeah, "yank-last-arg" is not in the vi keybindings.
That's why setting an environmental var is the way to go big_smile

Offline

#15 2010-05-24 08:07:00

gaudencio
Member
Registered: 2009-03-30
Posts: 33

Re: VERY simple find and execute script to be improved

Just after I went to bed lastnight I figured out the simplest way (i.e. only way I understand) to do what I wanted - just put it as a function in your .bashrc file.  Export doesn't work from a script back to the shell it was called from - that's what I was trying to say last night. So then, the final function is this:

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
}

This works great. If any newbies stumble upon this page (I've been looking for something like this since I started using the command line) then I'll briefly run through how it works:
1 - you type "fns x" where x is a word or partial word you know is in the filename
2 - you select whichever of the found files/directories you want
3a - you can then enter a command to run (e.g. vim)
3b - or just hit ctrl-c to return to the prompt, and then use $X in place of wherever you would have put the path in the command you want to run. e.g. "cd $X" will move you to that directory, if it was a directory you were looking for

Hope this helps someone

As for the other options from Procyon/karol - thanks, but again, over my head. I don't think I have xdotool installed. Script didn't work anyway, but mine is fine for now.
Thanks

Offline

Board footer

Powered by FluxBB