skip to Main Content

For some background I am using Windows Subsystem for Linux on Ubuntu 18.04. I am very new to bash scripting so there may be errors that seem obvious but I have not managed to find an answer online.

I am trying to set subj to be ‘S’ followed by the id number. I am also trying to replace all instances of S201 in the design.fsf file with subj, so it will run it with all IDs as it repeats the script.

#!/bin/bash                                                                                                                                                                                                             

for id in $(seq 204 204) ; do
subj="S$id"
echo "===> Starting processing of $subj"                                
echo                                                                    
cd "$subj" || exit 

sed -i "s/S201/${subj}/g" design.fsf

echo "===> Starting feat for run 1"

feat design.fsf                                                                                                                                                                                                                                                                                          

echo 

done

(Please note that usually the sequence in seq is 204-209 but to avoid it running the same issue over and over, I just substituted in 204 so it won’t try and run it on each number)

My problem: when it runs, it returns:

===> Starting processing of S204
===> Starting feat for run 1
can't read "subj": no such variable while executing
"set fmri(outputdir) "/usr/local/fsl/data/subjects2/{$subj}""
(file "/usr/local/fsl/data/subjects2/S204/design.fsf" line 33)
invoked from within

"source ${filename}"
(procedure "feat5:load" line 27)
invoked from within

"feat5:load -1 1 ${fsfroot}.fsf"
(file "/usr/local/fsl/bin/feat" line 309)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              

If you could explain your correction so I understand to apply it in the future that would be extra helpful and I’d really appreciate it. TIA.

Note: I have run this through ShellCheck which says it is fine.

2

Answers


  1. You must have a corrupted file "/usr/local/fsl/data/subjects2/S204/design.fsf" line 33 from a previous failed attempt; you have to reconstruct the corrupted line(s).

    Login or Signup to reply.
  2. The problem is in whatever feat is – it’s the thing reporting an error and it’s telling you the error is that it can't read "subj" at file "/usr/local/fsl/data/subjects2/S204/design.fsf" line 33 while trying to execute the command set fmri(outputdir) "/usr/local/fsl/data/subjects2/{$subj}"

    I suspect correcting your shellcheck issues actually solved your problem but when you ran your tool previously sed -i 's/S201/${subj}/g' design.fsf (with single quotes) replaced S201 with the literal string ${subj} so now when you run sed -i "s/S201/${subj}/g" design.fsf (with double quotes) there is no S201 in design.fsf and so the replacement doesn’t happen and then feat is still trying to work with input that contains $subj. You need to revert design.fsf back to where it contained S201 then run your tool again.

    To fis the problem so you can iterate through multiple $subj values, change sed -i "s/S201/${subj}/g" design.fsf; feat design.fsf to sed "s/S201/${subj}/g" design.fsf > tmp.fsf && feat tmp.fsf or similar so you don’t overwrite your original file that has the S201 in it so that’s still available for replacement on every iteration.

    I’d modify your script to:

    #!/usr/bin/env bash                                                                                                                                                                                                             
    
    tmp=$(mktemp) || { ret="$?"; echo "Failed to create tmp file" >&2; exit "$ret"; }
    trap 'rm -f "$tmp"; exit' 0
    
    for id in {204..204}; do
        subj="S$id"
        echo "===> Starting processing of $subj"                                
        echo                                                                    
        cd "$subj" || { ret="$?"; echo "Failed to cd to "$subj"" >&2; exit "$ret"; }
    
        sed "s/S201/$subj/g" design.fsf > "$tmp" || { ret="$?"; echo "Failed to sed design.fsf" >&2; exit "$ret"; }
    
        echo "===> Starting feat for run 1"
    
        feat "$tmp"  || { ret=$?; echo "Failed running feat "$tmp"" >&2; exit "$ret"; }
        echo 
    
    done
    

    Note that sed "s/S201/$subj/g" is fragile as it’d modify text that contains S201 as a substring, e.g. LOSS201BAD so you might want to tighten up that regexp with word boundaries and/or other delimiters.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search