1

I have the following bash loop.

for file in /home/directory/*; do
filename=${file##*/}
echo "$filename"
##execute command here with $filename
done

How can I select only certain files? For example, only selecting files without "mask" in their filename, e.g. test-file.zip. Additionally in each loop iteration I want do declare a variable with a "mask" added, i.e. test-file-mask.zip. How can I do this?

Edit:

I think I have to be more precise. ;) So I have a folder with lots of files, for example

test_001.nii.gz
test_001-mask.nii.gz
test_002.nii.gz
test_002-mask.nii.gz
....

That means for each file, there is also a "mask" file. Now I want in each loop iteration to select both the file without mask and the file with mask. For example in the first loop iteration $file should point to test_001.nii.gz and $mask should point to test_001-mask.nii.gz and in the second loop iteration $file should point to test_002.nii.gz and $mask to test_002-mask.nii.gz etc.

  • I'm confused which one of the mentioned things this question is actually about. What do you mean by "declare a variable"? Would the file "masked-gentleman.zip" be selected by your criteria? – Anko May 13 '15 at 9:56
  • I have edited the description – machinery May 13 '15 at 10:29
1

Using find and sed:

#!/bin/bash
find /home/directory/* -type f -name '*.gz' \
-not -name '*mask*' | while IFS= read -r file; do

    mask="$(sed 's/^\([^.]*\)/\1-mask/' <<<"$file")"

done

Consider any directory name does not contain the string mask.

  • Thank you for your answer. I have an additional problem. I want a variable $brain which should be equal to $file but the directory should be different. E.g. when $file is /home/directory/test.nii.gz then $brain should be /home/new_directory/test.nii.gz How can this be achieved? – machinery May 13 '15 at 17:10
  • @Thomas: Use brain="$(sed 's:^\(/[^/]\+/\)\([^\]\+\):\1new_\2:'<<<"$file")" – heemayl May 13 '15 at 17:32
2

In [[ ... ]], the right hand side of a == can be a pattern:

for file in /home/directory/* ; do
    if [[ $file != *-mask.nii.gz ]] ; then
        filename=${file##*/}
        mask=${filename%.nii.gz}-mask.nii.gz
        echo "$filename" "$mask"
    fi
done
  • Note that in bash-4.3.tar.gz, $extension above would be 3.tar.gz – Stéphane Chazelas May 13 '15 at 10:06
  • @StéphaneChazelas: Yes. But if the desired extension is tar.gz, the problem is very hard :-) – choroba May 13 '15 at 10:07
  • @choroba I have update the description, see above – machinery May 13 '15 at 10:29
  • @Thomas: I've updated the answer. – choroba May 13 '15 at 11:09

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.