Elena Pozzi
Elena Pozzi

Reputation: 23

Copying file from a directory with greater size in a loop bash

I apology in advance if the question is very basic.

I need to copy some files from a location to another. I am trying to write a script in bash that automates the process. To make into a loop, I am using a list and wildcards because the naming of the files is not consistent. What I have is (please note that the ' should be `):

for subject in cat 'subjects_list.txt' ; do
    cp /input/$subject/*_task/*_task-file.nii /output/$subject/dir1/${subject}_task-file.nii
done

This all works fine, the problem is that sometimes there are 2 directories called '*_task' in a subject directory, with a file *_task-file.nii each. However, one of these files is not complete, but because of the wildcard, the script grabs both. I would like to add in my script a way to check if there is more than one directory called task, and if so grab the *_task-file.nii with a greater size (and discard the other one - greater size should mean that the file is complete). I know that I can use wc -c $file to check for a file size. However, I don't know what would be the simplest way (my bash knowledge is pretty basic) to write in my script to only copy the file with a greater size. If anyone would be happy to point me in the right direction so that I can give writing a script a go, I would really appreciate.

Thank you!

Upvotes: 1

Views: 304

Answers (1)

KamilCuk
KamilCuk

Reputation: 141040

what would be the simplest way (my bash knowledge is pretty basic) to write in my script to only copy the file with a greater size.

  • Print the files as a list with filename and size stat.
  • sort the list on size.
  • Get the last (or first, depending on sorting order) element of the list. tail or head
  • Extract the filename cut
  • Copy that element.

Something along:

file_with_greatest_size=$(
    stat -c '%s %n' /input/$subject/*_task/*_task-file.nii |
    sort -k1n |
    tail -n1 |
    cut -d' ' -f2-
)
cp "$file_with_greatest_size" /destination

# with xargs it could be just: 
#     | xargs -d'\n' -I{} cp {} /destination
# without a temporary variable

Notes:

Upvotes: 1

Related Questions