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.

3
  • 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, 2015 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, 2015 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, 2015 at 3:05

2 Answers 2

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .