1

I am trying to write a script on a Debian Jessie host.

I am having an issue with trying to run the following command (with a twist) in a script:

find ~/* -path ~/FileSniper* \
-prune -o \
-type f \( -name "*.mp4" -o -name "*.sh" -or -name "*.mp3" \) \
! -name '*.txt' -printf "%f\n"

What I am trying to do in the script is make the user have to type in the file formats he/she wants to search for, after that, I pipe this to sed, which will make sure it obtains the right format:

 echo "Input the formats like this: \"mp3,mp4,exe,sh\""
        read -p "input:" formats
        formattedformats=`echo "-name \"*.""$formats""\"" | sed 's/,/" -o -name "*./g'`
        find_parameters=(\(formattedformats\))

Here the $find_parameters will contain something like:

-name "*.mp3" -o -name "*.mp4" -o -name "*.sh" 

I can't figure out what is wrong with this line:

find ~/* -path ~/FileSniper* -prune -o -type f  "${find_parameters[@]}" ! -name "*.txt" -printf "%f\n" > foundfiles.txt

I have researched what I could, but still haven't been able to figure out what is wrong. Please point me in the right direction.

  • If 'users' are running this script, -path ~/FileSniper* refers to their home directory. Also, try putting the full path to find instead of find like: /usr/bin/find also you are echoing to a file without putting the full path to the file. Try fixing all the relative path issues and possible $PATH issues and see if that fixes it. Once you have done these fixes, and if it still doesn't work, it might be easier to debug it. – Lizardx Nov 9 '15 at 2:45
  • is there a reason for ~/* ? are you trying to exclude hidden . directories? you could do find ~ -not -path '*/.*' ... instead. – cas Nov 9 '15 at 2:56
  • i would also advise taking the input as command-line arguments rather than prompting and reading stdin - that way it's easier to re-use your script from other scripts just by calling it as, e.g., scriptname.sh mp3 mp4 exe sh – cas Nov 9 '15 at 3:05
1

Here's a script that reads the file extensions from the command line (rather than from stdin) and uses them to build a regular expression to use with find's -iregex option.

It excludes hidden . directories and ~/FileSniper* as in your original example.

#! /bin/bash

regexp=''

for ext in "$@" ; do
    [ -n "$regexp" ] && regexp="$regexp\|"
    regexp="$regexp.*\.$ext$"
done

find ~ -not -path '*/.*' -not -path '*/FileSniper*' -type f \
    -iregex "$regexp" > foundfiles.txt
1

If your script is a #!/bin/sh type or is otherwise just .sh then it would explain why your ${find_parameters[@]} doesn't work on a Debian system which uses a default dash shell interpreter that doesn't implement the ${array[@]} type name extension.

I can also see how your -path ~/FileSniper* argument might come off with unwanted results - and the same goes for ~/* for that matter. As written those are shell expansions - not find expansions. The find [ ...paths... ] operands never expand and so ~/* - if that's really what you want - is as correct as it might be, but -path ~/FileSniper* is expanded to whatever the results might be by the parent shell before it is used as a pattern by find. And so if it doesn't match a ~/ path it is a moot point because * will remain as is anyway, but if it does then it no longer works as the pattern you intend.

You should quote it, probably: find ... -path ~/FileSniper\* unless you mean to look for a literal ~ tilde, in which case you should quote that, too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.