#!/bin/csh -f # normalize_filename_part # ------------------------------------------------------------------------------ # Shell script to normalize a piece of a filename. Reads a case-insensitive # simple filename (not full path) from the command line or stdin and echoes it # in the case (upper, lower, or some combination) in which it exists in the # current directory. Strips off any optional trailing slash (/). # Filename may optionally start with a slash (/) to operate on a filename at # the root of the filesystem, in which case the leading slash is preserved. # If the file does not exist, writes an empty string and returns 1 (error) # instead of 0 (success). # ------------------------------------------------------------------------------ # Assumptions: # Effects: # - Echoes filename to stdout # Notes: # Implementation Notes: # - Could re-write to take advantage of the fact that the C shell "pwd" # builtin command returns a normalized path, unlike "echo $PWD" and # "echo $cwd" which return the mix of case that the user specified on # the cd command on case-tolerant systems like Mac OS X. # - Or maybe not. On Mac OS X Snow Leopard, pwd normalizes when used # interactively, but not when called as: # set normalized_cwd = "`pwd`" # Weird! # Portability Issues: # Revision History: # $Log$ # ------------------------------------------------------------------------------ if ("$1" == "-h" || "$1" == "--help") then echo "Usage: $0:t [simple_filename | /simple_filename]" echo "Example: $0:t" echo "Example: $0:t abc.def" echo "Example: $0:t /Users" exit 1 endif # Get the arg from the command line or stdin if ($#argv == 0) then set name = $<:q else set name = $1:q endif # Strip trailing slash since :t below keeps only the stuff after the last slash. # We want the last part of the path, ignoring the optional trailing slash, # not the empty string following the optional trailing slash. set name = "`echo $name:q | strip_trailing_slash`" # If the name starts with a slash, cd to the root directory so that ls # will find it, and remember to prefix the answer with a /. # Otherwise, expect the file to be in the current directory. set prefix = set firstchar = "`echo $name:q | cut -c 1`" if ("$firstchar" == "/") then cd / set prefix = "$firstchar" endif # Use ls to get all names in the current directory, with whatever case # they were defined with, and filter out all but the specified name. # -d = Show names of directories, not their contents # -1 = One name per line # .* * = All files, including those that start with "." # -F = Search for fixed strings only, not patterns like ".". # -i = Case-insensitive search # -x = Search for whole line matches only # '' = Needed to cause grep to treat multiword filenames (w/embedded # spaces) as a single pattern, not a pattern followed by filenames. set name = "`ls -d -1 .* * | grep -F -i -x '$name:t:q'`" if ("$name" == "") then echo $name exit 1 else echo $prefix$name exit 0 endif