1

All I want to do is to search a directory of files for ANY part of a string. Here is the section of my code that processes this:

(input is set through user input)

input2=$(eval find . -name "$input" -print | sed -n 1p) #Using find to search for the file I need to read

... (Checking the file I 'found' actually exists)

out=$(eval $(shuf -n 1 "$input2")) #Shuffle it randomly

echo "$out" #Echo the output

If I had the file 'date' with the contents date "+%A %d %B %Y" I could type 'date' and get the intended result but 'What is the date' would fail with

find: paths must precede expression: is 
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

What is the easiest way to fix this problem?

edit

I haven't tried much as I am at a loss of what to do. I have tried wildcards in the search string but they don't work at all. Here is the entire input-to-output part of the source code:

while true; do

  echo -n ">"
  read input
  input=${input,,}

  echo "[DEBUG]: Recieved $input"

  echo "[IO]: Accessing database"

  input2=$(eval find . -name "$input" -print | sed -n 1p) || out="WARNING: Input/Output Error{TYPE=IO.GENERAL, VALUE=$input2}"

  echo "[INPUT2]: Recieved $input2"

  if [ ! -f "$input2" ]
  then
    input2="./db/unknowncommand"
  fi

  #out=$(<"db/$input") || out="WARNING: Input/Output ERROR" #Old 'just print whatever is in the file approach

  out=$(eval $(shuf -n 1 "$input2")) || out="WARNING: Input/Output ERROR{TYPE=IO.GENERAL, VALUE=$input}" #Random output

  echo "$out"
  ./JAISpeak "$out" #A small text-to-speech program I made

done
Community
  • 1
  • 1
its_notjack
  • 323
  • 3
  • 17
  • Are you trying to search _filenames_ for an input string, or search through the files themselves? – Jeff Bowman Oct 06 '14 at 18:36
  • please, show your REAL work = what you really tried. The above is only holy praying what you want be done... – clt60 Oct 06 '14 at 18:42
  • Is [this](http://stackoverflow.com/questions/229551/string-contains-in-bash) relevant? – Travis Oct 06 '14 at 18:48
  • @TravisJacobs Yes, that's the idea, I just need to read the filename and see if my string is contained in it. – its_notjack Oct 06 '14 at 18:51
  • @JeffBowman I'm trying to search the **filenames**, _not the contents of the files_, to clarify. – its_notjack Oct 06 '14 at 18:52
  • @JackMawer could you `ls` the files in your dir, then `grep` for the desired string? Wildcards would work with `grep`. – Travis Oct 06 '14 at 18:55
  • If i understand : you want the input "what is the date" to look for filenames that contain either "what" or "is" or "the" or "date" ? – Olivier Dulac Oct 06 '14 at 18:57
  • have you tried `grep date *`? – Diego Torres Milano Oct 06 '14 at 18:59
  • @OlivierDulac that is the general idea. The point is that I will _never_ have a file in my 'database' named 'what', 'is' or 'the' so only date would match, but doing it this way would mean I could say anything with the word 'date' in it and probably get the intended answer to my question. – its_notjack Oct 06 '14 at 19:00
  • I see the problem : the eval will evaluate "$input2", and find will have then to "find . -name what is the name ....", so it sees "is" as something that ought to be a path as it doesn't recognise a command there. You need to drop the eval, first. but also you need to loop over $input2 if you want to look for each words separately – Olivier Dulac Oct 06 '14 at 19:01
  • @dtmilano This wouldn't solve the problem, because my file is called 'date' and I am trying to find the word date in the string 'What is the date?' (for example). In short, `date` **=** `what is the date?` – its_notjack Oct 06 '14 at 19:02
  • and "${input,,}" looks wrong... on my (old) bash it doesn't parse, and is an error. Do you mean : `input2="${input}"` ? (why the 2 commas?) – Olivier Dulac Oct 06 '14 at 19:03
  • @OlivierDulac The find without the eval seemed to turn up a blank string every time, and sometimes an error saying find doesn't exist. On a whim, I added eval and it worked fine. – its_notjack Oct 06 '14 at 19:13
  • @OlivierDulac the $(input,,) is a bash 4.0 thingy that converts the string to lowercase so it matches any case – its_notjack Oct 06 '14 at 19:16

1 Answers1

0

For the "look for any part of the string in filenames" part, I'd do:

input2=$(for partname in ${input}; do find . -name "${partname}" -print ; done)

This will match every occurrence it can... If you only need the first occurrence (weird, but hey, it's a bit the same with $PATH) :

input2=$(for partname in ${input}; do find . -name "${partname}" -print ; done | head -1)

Note that i use ${input} instead of "${input}" on purpose: I want to separate each words in ${input} and loop over each one individually.

I let you revise the rest of your program ^^ (I need to go ...)

Darren Cook
  • 27,837
  • 13
  • 117
  • 217
Olivier Dulac
  • 3,695
  • 16
  • 31