Helpful UNIX notes
Here are some UNIX pointers that might be helpful to Language Comprehension Lab UNIX user as well as to others.


Shell Scripts
Shell scripts are merely text files that are Unix commands. So, to write a shell script, simply make a file with Unix commands that are to be executed sequentially. The first character in the file must be a '#', and the file must be executable determined by 'chmod'. A shell script may be very basic, or it may be very complex.

One thing that is usefull for fMRI processing is a for or foreach loop. Since each study can contain a number of subjects and scans for each subject, processing will be facilitated if a shell script can be made to do the same thing for each subject and/or scan.

For example, if you wanted to copy certain files from each subject into a single file for the study, a shell script is much easier than doing it manually. The shell script could look something like this:
#
mkdir RandFX

foreach sub (1 2 3 4 5)
     cd subj{$sub}
     cd results
     foreach con (02 03 04 05 06 07 08)
          cp con_00{$con}.img ../../RandFX/{$sub}con_00{$con}.img
          cp con_00{$con}.hdr ../../RandFX/{$sub}con_00{$con}.hdr
     end
     cd ..
     cd ..
end

This script would take each of 8 contrasts for 5 subject and copy them to the RandFX directory. The way to execute this would be to copy it into the directory containing the subject directories and simply type the name of the script.

An easier and more efficient way of doing this is to add the two lines:
set here = $PWD
cd $here
at the beginning of the script (the line after the #) to allow the script to be run from anywhere. Thus, the script will determine the working directory and start the script from there (as long as the script location is in the unix path).
The most helpful Unix command you'll ever use, maybe
To issue a command on a large number of files can be time consuming & difficult. A shell script may do the job, but these can be more time than they're worth. A solution: piping.

A pipe '|' in a unix command simply passes the output of a command in a sequence to the next. For instance:

%: ls | more

allows the output of ls to be scrolled by the more command. To execute a command on a large set of files can be done by piping to sed.

sed (stream editor) is a method of editing text. The use of sed can be used to (somewhat) easily issue commands on files that would otherwise be difficult to do (such as where a program only allows one file as input, like mv). Sed will only output the textual commands, it will not execute them. (sed if far more powerful than what is described here. For more info, check the sed man page on you unix shell) This will be taken care of by piping the output to a shell for execution. For our purposes, sed command works like this:

sed -e 's(for substitution)/replacethis/withthis/thistimeitoccurs'.

The .* replaces the entire line, and the & is the enitre thing being replaced. Thus, if we had some files named scan1.###.img and wanted to change the scan1 to a subject number, first we do a ls

%: ls scan1*.img

which will list all of our files. Piping them to sed will allow us to do substitution on the names.

%: ls scan1*.img | sed -e 's/.*/mv & &/'

the will output the line

mv scan1.###.img scan1.###.img

for each of the files. Now, since we want to change the the second instance of the filename, we add:

%: ls scan1*.img | sed -e 's/.*/mv & &/' -e 's/scan1/subj1/2'

which produces the line

mv scan1.###.img subj1.###.img

for every file. Now that every line has the command that we want to execute, if we pipe to the sh command, each line will get executed. Thus:

%: ls scan1*.img | sed -e 's/.*/mv & &/' -e 's/scan1/subj1/2' | sh

will rename each scan1.###.img file to a subj1.###.img file. The best way to test this out is to play around with the ls and sed portions to get the output to look exactly like you want it to be executed, and only once that is correct should you add the '| sh' portion. It can also be piped to awk before being piped to the shell to do things like adding or subtracting a number from the ### in the file name or consecutive series format (Siemans) to a image-slice format (GE), but this is beyond the scope of this discussion.

back to top