2

I am trying to use this script:

#!/bin/csh
foreach SUB (1 2 3 4 5 6 7 8 9 10 11 12 13 14)
    echo $SUB
    foreach VISIT (1 2 3 4 5 6 7 8)
        echo $VISIT
        grep 'StudyDate' -f  /home/colourlab/Desktop/DrummingDTI/D${SUB}/D${SUB}V${VIS}/scout/001/infodump.dat
    done
done

but every time I receive this error message:

1
1
SUB: Undefined variable.

and I don't know why.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
  • do NOT use csh... really. Too many bugs to list them all, and sometimes very weird behaviors as well. See for example: http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/ or http://www.grymoire.com/Unix/Csh.html#uh-0 or http://www.grymoire.com/Unix/CshTop10.txt ... switch to a bourne-compatible shell (bash is nice, zsh even better but less present on some older platforms.) – Olivier Dulac Apr 05 '17 at 16:30

2 Answers2

5

Aside from all the reasons scripts shouldn't be written in csh, you are mixing bash syntax and csh syntax in your script.

You're starting your loop with the csh foreach and trying to finish them with the bash done. The loop exit for a csh foreach is end, not done. Also, you have a variable VISIT that you are calling $VIS in your grep statement.

So you script would be syntactically correct in csh with:

#!/bin/csh
foreach SUB (1 2 3 4 5 6 7 8 9 10 11 12 13 14)
    echo $SUB
    foreach VISIT (1 2 3 4 5 6 7 8)
        echo $VISIT
        grep 'StudyDate' -f  /home/colourlab/Desktop/DrummingDTI/D${SUB}/D${SUB}V${VISIT}/scout/001/infodump.dat
    end
end

or in bash:

#!/bin/bash
for SUB in 1 2 3 4 5 6 7 8 9 10 11 12 13 14; do
    echo $SUB
    for VISIT in 1 2 3 4 5 6 7 8; do
        echo $VISIT
        grep 'StudyDate' -f  /home/colourlab/Desktop/DrummingDTI/D${SUB}/D${SUB}V${VISIT}/scout/001/infodump.dat
    done
done

EDIT 2017/04/03

Here's a version of the bash script that adds a test for the file:

#!/bin/bash

idf_pfx="/home/colourlab/Desktop/DrummingDTI"
idf_sfx="scout/001/infodump.dat"

for SUB in 1 2 3 4 5 6 7 8 9 10 11 12 13 14; do
    echo $SUB
    for VISIT in 1 2 3 4 5 6 7 8; do
        echo $VISIT
        idfile="${idf_pfx}/D${SUB}/D${SUB}V${VISIT}/${idf_sfx}"
        if [ -f "${idfile}" ]; then
            grep 'StudyDate' $idfile
        else
            echo "No studydate file: $idfile"
        fi
    done
done
vy32
  • 194
Tim Kennedy
  • 19,697
  • Thanks But I still got some error massages and I am sure I have those files in the dir ; 1 1 grep: /home/colourlab/Desktop/DrummingDTI/D6/D6V1/scout/001/infodu‌​‌​mp.dat: No such file or directory and when I was trying to use the second script I got this error massage ; ./test: line 4: syntax error near unexpected token do' ./test: line 4: foreach VISIT in 1 2 3 4 5 6 7 8; do – Manal Os Mar 29 '17 at 15:26
  • Apologies, @ManalOs, I left a foreach in the bash example. I have removed it. The other error about no such file or directory, is because the path the script is building isn't leading to a file. You need to check the variable expansions in the file path, and make sure you're not missing a slash or something. Or maybe that file just doesn't exist. – Tim Kennedy Mar 29 '17 at 17:58
  • Thanks Tim again, what is the best way to check the file if it exist or not ? I still having the same error massages ! grep: f-infodump.dat: No such file or directory grep: /home/colourlab/Desktop/DrummingDTI/D14/D14V8/scout/001: Is a directory – Manal Os Apr 03 '17 at 10:34
  • in bash, you can test the existence of a file with a simple if [ -f $file ]; then test. I've added an example for you. – Tim Kennedy Apr 03 '17 at 14:53
  • Thanks a lot but I still had an error massage called ; No studydate file: /home/colourlab/Desktop/DrummingDTI/D14/D14V8/scout/001/infodump.dat . However, just to make sure that you are understand what I doing here . I am looking to find this word (studydate) under file name called (f-infodump.dat) at this dir ;/home/colourlab/Desktop/DrummingDTI/D1/D1V1/scout/001 , and I am still don't know where is the mistake ! – Manal Os Apr 04 '17 at 08:55
  • That's not an error. That's an informational note supplied by the script above, in this line: echo "No studydate file: $idfile". The mistake is that you original example had the filename infodump.dat, not f-infodump.dat, so all of my examples have done the same. Edit the script to look for the right filename and you'll have a better outcome. – Tim Kennedy Apr 04 '17 at 14:42
  • I got this massage ;( grep: Invalid back reference) ! and thanks for trying help me to do this – Manal Os Apr 05 '17 at 09:02
  • ah, yeah. your grep syntax was off. grep -f <file> would mean that you're searching for the patterns that are enumerated in <file>. Which is not what you want here. Take the -f out of the grep, and your results should be more like what you actually want. – Tim Kennedy Apr 05 '17 at 15:53
  • 2
    Another reason to not use csh: fun with $PATH. Wait. Or is that $path?!?! Note in the answer there that $path in csh is space-delimited. I have never tested what happens if a directory with a space in its name is put into csh's $path... – Andrew Henle Apr 05 '17 at 16:13
0

Your error message does not match the code that you are showing. $SUB is a well defined variable and csh will not crib about it. Rather csh will emit the error "done: command not found" which you should have got. Are you sure you copy-pasted the correct message?