1

I am trying to clear multiple directories stored in an array. Here's a simplified example (I have more directories).

#!/bin/bash    

$IMAGES_DIR="/Users/michael/scripts/imagefiles"
$BACKUP_DIR="/Users/michael/scripts/imagebackups"

...

array=( $IMAGES_DIR $BACKUP_DIR )
for i in ${array[@]}
do
    if [ "$(ls -A $i)" ]; then     # check that directory has files in it
        rm "$i/"*                  # remove them 
    fi
done

I get errors for each directory, e.g.:

rm: /Users/michael/scripts/imagefiles/*: No such file or directory

3

How about accomplishing it all in a single command?

You can capture the file existence check, globbing and removal with one find call. In the case of GNU's version of find we'd have this:

for f in "${array[@]}"; do
     find "$f" -type f -delete
done

If you don't have GNU find use this invocation:

find "$f" -type f -exec rm -f {} +

(If instead of clearing files from the entire directory hierarchy you only want to clear files that are immediate children then add -maxdepth 1 before -type f.)

But wait, there's more....

As John1024 wisely notes you can forgo the loop altogether by passing the array as the first parameter to find:

     find "${array[@]}" -type f -delete

That's because: 1) find will accept multiple directories to be searched and processed in one execution 2) the shell will split the array such that each element (directory) becomes an individual positional parameter to find.

  • 1
    Simpler: find "${array[@]}" -type f -delete – John1024 Dec 24 '17 at 3:53
  • 1
    Good one @John1024 ... I shoulda thought of that. – B Layer Dec 24 '17 at 3:54
1

Change your code to this:

#!/bin/bash    

IMAGES_DIR="/Users/michael/scripts/imagefiles"
BACKUP_DIR="/Users/michael/scripts/imagebackups"

array=( $IMAGES_DIR $BACKUP_DIR )
for i in "${array[@]}"
do
    if [ "$(ls -A "$i")" ]; then     
        rm "${i:?}"/*                 
    fi
done

Errors:

  1. Placing $ on the left hand side of variable assignments
  2. Not quoting the $i in if [ "$(ls -A $i)" ];then
  3. Use "${var:?}" to ensure this, rm "$i/"* never expands to /*
  • Ok tested on two directories and worked! – George Udosen Dec 24 '17 at 3:27
-1

Please find the below awk oneliner to achieve the same , As tested it worked fine


i="/root/";ls -ltr /root/| grep "^-rw" | awk -v i="$i" '{print "rm -rvf" " " i$9}' | sh  

for example i have assigned variable i = path /root/ you can change as per your requirement

i="/root/" ===> path

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.