AS12517
AS12517

Reputation: 11

How to check filetype in if statement bash using wildecard and -f

subjects_list=$(ls -l /Volumes/Backup_Plus/PPMI_10 | awk '{ print $NF }')

filepath="/Volumes/Backup_Plus/PPMI_10/$subjects/*/*/S*/"
for subjects in $subjects_list; do
    
    
    if [[ -f "${filepath}/*.bval" && -f "${filepath}/*.bvec" && -f "${filepath}/*.json" && -f "${filepath}/*.nii.gz" ]]; then

echo "${subjects}" >> /Volumes/Backup_Plus/PPMI_10/keep_subjects.txt

else
        echo "${subjects}" >> /Volumes/Backup_Plus/PPMI_10/not_keep_subjects.txt
    
fi

done

problem is supposedly in the if statement, I tried this...

bvalfile = (*.bval)
bvecfile =(*.bvec)
jsonfile =(*.json)
niigzfile =(*.nii.gz)
    
    if [[ -f "$bvalfile" && -f "$bvecfile"  && -f "$jsonfile" && -f "$niigzfile" ]]; then

however that didn't work. Any help with syntax or errors or does it need to be changed completely. Trying to separate the files that have .^file types from those that don't by making two lists.

thanks

Upvotes: 1

Views: 64

Answers (1)

Mark Reed
Mark Reed

Reputation: 95315

  1. You're assigning filepath outside the for-subject loop but using the unset variable $subjects in it. You want to move that inside the loop.
  2. Double-quoted wildcards aren't expanded, so both $filepath and your -f test will be looking for filenames with literal asterisks in them.
  3. -f only works on a single file, so even if you fix the quotes, you'll have a syntax error if there's more than one file matching the pattern.

So I think what you want is something like this:

# note: array assignment - 
# shell does the wildcard expansion, no ls required
prefix_list=( /Volumes/Backup_Plus/PPMI_10/* )

# and array expansion
for prefix in "${prefix_list[@]}"; do

  # the subject is just the last component of the path
  subject=${prefix##*/}

  # start by assuming we're keeping this one
  decision=keep

  # in case filepath pattern matches more than one directory, loop over them
  for filepath in "$prefix"/*/*/S*/; do

    # if any of the files don't exist, switch to not keeping it
    for file in "$filepath"/{*.bval,*.bvec,*.json,*.nii.gz}; do 
      if [[ ! -f "$file" ]]; then
        decision=not_keep
        
        # we have our answer and can stop looping now
        break 2
      fi
    done
  done

  # now append to the correct list
  printf '%s\n' "$subject" >>"/Volumes/Backup_Plus/PPMI_10/${decision}_subjects.txt"
done


      
    
  

Upvotes: 2

Related Questions