Created
March 14, 2010 01:07
-
-
Save zach-klippenstein/331685 to your computer and use it in GitHub Desktop.
Returns the path passed to it with the case of components modified to match the actual names. See the comment header for more details.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# usage: caseglob [--rename] path | |
# Prints the path, with the basename corrected to the actual case of the file, if | |
# a match can be made. | |
# | |
# If --rename is specified, if an unambiguous match is found, it will be renamed to | |
# path and returned in the original case. | |
# | |
# If there are 0 or more than 1 matches, the original basename is printed. | |
# If any of the components of the path don't exist, they are globbed as well. | |
# If a match couldn't be made, the path printed is as similar to the argument | |
# as possible: any recursive matches that could be made are included, but | |
# any non-existent or multiple matches are printed as given. | |
# | |
# Return values: if a unambiguous match was made, returns 0, else 1. | |
# | |
# By: Zachary Klippenstein | |
# On: 13/03/2010 | |
# If this is set to a non-empty string, if a match is found, it will | |
# be renamed to the argument's version. | |
rename="" | |
# Process arguments | |
while [ "$(echo "$1" | egrep '^--.')" ]; do | |
case "$1" in | |
--rename) | |
# Set to the name of the option so it can be passed when recursing | |
rename="--rename" | |
;; | |
esac | |
shift | |
done | |
origPath="$1" | |
origDir="$(dirname "$origPath")" | |
origBase="$(basename "$origPath")" | |
echo -e "`date`\nChecking for '$origPath'..." >>/tmp/caseglob.log | |
if [ -d "$origDir" ]; then | |
# Case-insensitive search for the actual filename | |
# NOTE: - fgrep searches for fixed strings, not regular expressions. | |
# - 'i' makes case-insensitive | |
# - 'o' only prints the part of the line that matches. This is important | |
# because if origBase is only part of a filename, without 'o' we'd get | |
# ALL the files that had origBase as part of their names. | |
# However, this might result in a name which doesn't actually exist, so | |
# we check for the existence of the file before returning successfully. | |
# - 'e' allows origBase to start with a dash ('-') | |
# - Even if there are no matches, grep will return a newline, so we must check | |
# for an empty string as well as line number. | |
actualBase="$(/bin/ls -1 "$origDir" | fgrep -ioe "$origBase")" | |
numMatches=$(echo "$actualBase" | wc -l) | |
# 3 cases: more than 1 file matched, no files matched, or exactly 1 file matched | |
# We'll treat the first 2 the same, and print the original path, but return an error. | |
# Found only 1 existing match (unambiguous) | |
if [ $numMatches -eq 1 -a "$actualBase" -a -e "$origDir/$actualBase" ]; then | |
# If rename was specified and cases are actually different, rename | |
if [ "$rename" -a "$actualBase" != "$origBase" ]; then | |
mv "$origDir/$actualBase" "$origDir/$origBase" | |
actualBase="$origBase" | |
fi | |
echo "$origDir/$actualBase" | |
exit 0 | |
# Either 0 or >1 matches: | |
# - if 0, let caller handle non-existent file normally. | |
# - if >1, | |
# if actual case exists, use that. | |
# if none of the matches are exact, let caller handle non-existent file | |
else | |
echo "$origDir/$origBase" | |
exit 1 | |
fi | |
# Containing directory not found, attempt recursion | |
else | |
# Recurse upwards to find actual name of containing directory | |
actualDir="$("$0" $rename "$origDir")" | |
# Directory was successfully found | |
if [ $? -eq 0 ]; then | |
# Recurse with actual directory name to find actual basename | |
actualPath="$("$0" $rename "$actualDir/$origBase")" | |
# Check that the actual path exists | |
if [ $? -eq 0 -a -e "$actualPath" ]; then | |
echo "$actualPath" | |
exit 0 | |
# Found the real containing directory, but the actual file doesn't exist | |
else | |
echo "$actualDir/$origBase" | |
exit 1 | |
fi | |
# Recursion failed to find the actual directory, exit with | |
# error and original path | |
else | |
echo "$origDir/$origBase" | |
exit 1 | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment