2

I want to be able to run a find command in my bash script that will find files based on two separate variables. I've gotten this far but I'm not sure how to get the final result working

find . -user $userid -name $filename

Here is the file of parameters I want to use:

cat $uidscript  
10017:title  
10001:options.php  
10005:dump.php(235)  

So on so forth, the variable contains the username and the file owned by the username.

I think I need to separate the userid and the filename into two separate lists.

userid=$(cat $uidscript|cut -c1 -d':')
filename=$(cat $uidscript|cut -c2 -d':')`

From here I'm not sure how to organise the find command into a for loop. I would think it would go something like this..

for i in $userid, $filename;
do 
    find . -user $userid -name $filename; 
done

Could someone give me a push in the right direction?

3 Answers 3

3

Use a while-read loop to process the lines of the file

while IFS=: read userid filename
do
    find . -user "$userid" -name "$filename"
done < "$uidscript"
0
3

While the other options are fine, I'd like to correct some mistakes in your approach:

userid=$(cat $uidscript|cut -c1 -d':'):

  • -c gets characters, you need fields. Use cut -f1 -d:.
  • Useless use of cat: Just do: cut -f1 -d: <"$uidscript".
  • Store the result in an array so you can iterate over it and another array easily:

    IFS=$'\n'  # split on newline
    set -f     # disable the glob part of the split+glob operator
    userid=($(cut -f1 -d: <"$uidscript"))
    
  • Same for the filenames.

Then you can loop over the indices of either array:

for i in "${!userid[@]}"
do 
    find . -user "${userid[i]}" -name "${filename[i]}"; 
done
1
  • @Stephane That's odd. I tested out that before posting (and added a space to an entry just to be sure), and I got three lines as expected. bash -c 'userid=("$(cut -f1 -d":"<blah)"); for i in "${!userid[@]}"; do echo "${userid[i]}"; done' gave me 10017, 10001 1, 10005 on separate lines. The parent shell is zsh, if it matters. Commented Jan 26, 2015 at 23:03
2

You could do:

IFS=:   # split on :
set -f  # disable glob part of the split+glob operator
echo find . $(
  awk -F: '
    {
      printf "%s", sep "(:-user:" $1 ":-name:" $2 ":):"
      sep = "-o:"
    }' < "$uidfile")

(remove the echo if that's the right command you want to run).

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.