Problem with File Names under tcsh loop

Hello,
I have a question regarding file naming under a loop in tcsh. I have the following code:

#!/bin/tcsh
foreach file (test/ProteinDirectory/*)   # The * is a bunch of ProteinFile1, ProteinFile2, ProteinFile3, etc.
sh /bioinfo/home/dgendoo/THREADER/pGenThreader.sh $file $file 
         #the first $file is really supposed to represent the filename, the second $file is the actual path!
echo DONE! $file#protein name is what I'm aiming for
end

The problem:
If I echo $file in the loop, it will print the entire path: test/ProteinDirectory/ProteinFile1
I want a way to only extract the actual file name (ex: ProteinFile1) to use in the loop to rename my files, and still retain the $file because I need that path as input.
So in that case the code would be something like:

#!/bin/tcsh
foreach file (test/ProteinDirectory/*)
set ProteinName = ?? 
           # Where ProteinName = ProteinFile1, ProteinFile2, etc. Probably some string manipulation on $file
sh /bioinfo/home/dgendoo/THREADER/pGenThreader.sh ProteinName $file
echo DONE! ProteinName
end
  1. Could you suggest a way to do this? I think it could be done in Sed with a / delimiter, but I am not very familiar with that language.

  2. I also wanted to try and modify this loop so that I only work on 200 ProteinFiles at one time, so I wanted some sort of condition to say "execute from ProteinFile5 to ProteinFile205". I would really appreciate some input on how to incorporate this condition into the loop also.

Thank you very much for your help!

To keep the forums high quality for all users, please take the time to format your posts correctly.

First of all, use Code Tags when you post any code or data samples so others can easily read your code. You can easily do this by highlighting your code and then clicking on the # in the editing menu. (You can also type code tags

```text
 and 
```

by hand.)

Second, avoid adding color or different fonts and font size to your posts. Selective use of color to highlight a single word or phrase can be useful at times, but using color, in general, makes the forums harder to read, especially bright colors like red.

Third, be careful when you cut-and-paste, edit any odd characters and make sure all links are working property.

Thank You.

The UNIX and Linux Forums

Don't know about tcsh but maybe this example can help a little :

# ls /opt/sfw/lib/*.so | head -2 >/tmp/input
# cat /tmp/input
/opt/sfw/lib/libFnlib.so
/opt/sfw/lib/libImlib.so
# while read line
> do
> echo "parsing1 = $line"
> echo "parsing2 = ${line##*/}"
> echo "parsing3 = $(basename $line)"
> echo "parsing4 = $(dirname $line)"
> echo "parsing5 = $(echo $line | sed 's|.*/||g')"
> done </tmp/input
parsing1 = /opt/sfw/lib/libFnlib.so
parsing2 = libFnlib.so
parsing3 = libFnlib.so
parsing4 = /opt/sfw/lib
parsing5 = libFnlib.so
parsing1 = /opt/sfw/lib/libImlib.so
parsing2 = libImlib.so
parsing3 = libImlib.so
parsing4 = /opt/sfw/lib
parsing5 = libImlib.so
#

Just feel free to test and adapt to your needs.

parsing 4 could also be written ${line%/*} (but i don't know whether tcsh handle it or not)

By the way, if you want to use sed in order to parse Path name that contains / you'd better go for a delimiter such as | or : instead of a / otherwise you would have to escape any / by a \ otherwise would be interpreted as a delimiter ...

1) echo $file | sed 's/.*\///'

2) ls will normally list in AN order, so to get them numerically sorted and grab a range:

ls test/ProteinDirectory/* |sed -n 's/^[^0-9]*\([0-9]*\)$/\1 &/'|sort -n|sed '
  /^'$start_no' ,/'$end_no'/!d
  s/.* //' 

Narrative:

  1. List the directory (will come out one file per line when to a pipe).
  2. Have sed find the only number part at the end and copy it to the front with a space.
  3. Sort the stream in forward numeric order.
  4. Have sed preserve the lines in the range, the remove the number and space prefix.

You can put this on a command line with `command string` or use 'xargs -n 19 your_cmd' to build and execute command lines of 1 to 19 file args. As I recall, xargs is a little squirrelly if you do not use -n, executing with no arguments. If you just want to do n at a time in any order, xargs -n will do that.

As xargs has been know to provide quoting challenges with funny things like file names (lines) with metachar or white space in them (it coposes an actual command line, I wrote fxargs and then fxargs2 to take lines directly to null terminated strings in an argv[] to pass to exec() without a command line. It saves a few cycles, too. The second one is smarter about building a command line of any # of args as input arrives while waiting for the last command execution to complete, so less time is lost, less latency. The first command might have 3 args, the next 6, and so on as input arrives.

I love modular tools. These each bridge a gap, like `` ksh $() and xargs go from stream/stdin to command line, echo goes from command line to stream/stdout. The beauty of xargs is that it scales up no limit. I write a lot of tools that take args on stdin as lines, not on the command line, so they are interchangable pipe fittings. I am a power user, I guess! :smiley:

My apologies. Will pay more attention when I post the next time.
I would still appreciate your feedback on my question though!
Thank you

---------- Post updated at 09:34 AM ---------- Previous update was at 09:26 AM ----------

Thank you ctsgnb and DGPickett for your responses!