reldir
来自「This is a resource based on j2me embedde」· 代码 · 共 256 行
TXT
256 行
#!/bin/sh### Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER# # This program is free software; you can redistribute it and/or# modify it under the terms of the GNU General Public License version# 2 only, as published by the Free Software Foundation.# # This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU# General Public License version 2 for more details (a copy is# included at /legal/license.txt).# # You should have received a copy of the GNU General Public License# version 2 along with this work; if not, write to the Free Software# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA# 02110-1301 USA# # Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa# Clara, CA 95054 or visit www.sun.com if you need additional# information or have any questions.######################################################################## convert an absolute path to relative path######################################################################if [ -z $AWK ]thenAWK=gawkfi# $1 -- path to be converted to relative# $2 -- dash, necessary to detect an empty $1# $3 -- base path# $4 -- limit path -- return an empty string if $1 is not a subdirectory of $3# $5 -- directory separator character, optional, "/" unless "\\" is specified# $6 -- variable name for the base path in the output;# for example, if it is MYDIR, the output path will start with "$(MYDIR)/"echo "$1" "$2" "$3" "$4" "$5" "$6" | $AWK '# remove the trailing slash from path# path -- path to be modifiedfunction striptrailingslash(path) { gsub(/\/$/,"",path); return path;}# if sep == "\\", replace backslashes in path with slashes# also, if sep == "\\", lowercase the path# path -- path to be modified# sep -- separator, either "/" or "\\"function toslash(path,sep) { if(sep == "\\") { gsub(/\\/,"/",path); path = tolower(path); } return path;}# return true (1) if path is absolute# path - file path, with "/" used as separator# examples:# /foo c:/foo //WINCOMP/DISKNAME/file http://foo.com/foo -- absolute# foo ./foo ../foo c:.. c:foo c:./foo -- relativefunction isabsolutepath(path) { return path~/^\//; # || path~/^[a-zA-Z_0-9]+\:\//}# append "/" to path, unless path is empty or "/" is already there# Note: make sure that path contains no protocol (ftp:) or drive (c:)function appendslash(path) { if(path~/[^\/]$/)path=path "/"; return path;}# extract device or protocol from path# examples: "c:" for "c:/foo"; "ftp:" for "ftp://foo.com/pub"function drive(path, dev) { dev = ""; if(match(path,/^[a-zA-Z_0-9]+\:/)) { dev=substr(path,RSTART,RLENGTH); } return dev;}# remove device or protocol from path# examples: "/foo" for "c:/foo"; "//foo.com/pub" for "ftp://foo.com/pub"function afterdrive(path) { if(match(path,/^[a-zA-Z_0-9]+\:/)) { path=substr(path,RSTART+RLENGTH); } return path;}# remove /../ and /./ from path;# path -- path, from which /../ and /./ is to be removedfunction stripdir(path, pathprefix){ pathprefix = ""; # separate drive letter ("c:") or protocol ("http:"), if any if(match(path,/^[a-zA-Z_0-9]+\:/)) { pathprefix=substr(path,RSTART,RLENGTH); path=substr(path,RSTART+RLENGTH); } if(match(path,/^\/+/)) { # move all leading "/" to pathprefix pathprefix=pathprefix substr(path,RSTART,RLENGTH); path=substr(path,RSTART+RLENGTH); } # append "/", unless path is empty or "/" is already there path = appendslash(path); # move all leading ./ and ../ to pathprefix while( path~/^\.\// || path~/^\.\.\// ) { if(path~/^\.\//) { sub(/^\.\//,"",path); } else { sub(/^\.\.\//,"",path); pathprefix = pathprefix "../" } } # remove duplicate slashes while(path~/\/\//)sub(/\/\//,"/",path); # remove /./ while(path~/\/\.\//)sub(/\/\.\//,"/",path); # temporarily prepend path with "/" path = "/" path; # remove pairs dirname/.. # NB this will not work if dirname is "..." (3 dots, or more) while(path~/\/[^\/]*[^\/\.][^\/]*\/\.\.\//) { sub(/\/[^\/]*[^\/\.][^\/]*\/\.\.\//,"/",path); } # remove pairs .../.. (easier to do this than to document a defect) while(path~/\/\.\.\.+\/\.\.\//) { sub(/\/\.\.\.+\/\.\.\//,"/",path); } # remove the temporary "/" in the beginning path = substr(path,2); return pathprefix path;}function commonroot(first, second, drv){ if(drive(first)!=drive(second)) { return ""; } drv = drive(first); first = afterdrive(first); second = afterdrive(second); if(first~/^\.\.\// || second~/^\.\.\//) { return ""; } if(first!~/\//) { first = "./" first; } if(second!~/\//) { second = "./" second; } first = appendslash(first); second = appendslash(second); while(second!=first) { # concatenation with a null string is a workaround for a bug # (on some systems, the reported length does not change # as the string changes) if(length("" second)>length("" first)) { sub(/\/[^\/]*\/$/,"/",second); } else { sub(/\/[^\/]*\/$/,"/",first); } } return drv first;}# return true if subdir is a subdirectory of parentdir;# false means that the algorithm could not find it out for sure,# for example, ../../foo/bar/x may be or not be a subdirectory of ../barfunction sureissubdir(subdir,parentdir) { subdir = stripdir(appendslash(subdir)); parentdir = stripdir(appendslash(parentdir)); return parentdir==substr(subdir,1,length("" parentdir)) \ && substr(subdir,1+length("" parentdir))!~/\.\.\//;}function reldir(targetpath,base, root,relpath,fromroot){ if(base == "" || targetpath == "") { return targetpath; } # convert to "canonic" form targetpath = stripdir(targetpath); base = stripdir(base); if(drive(targetpath) != drive(base)) { return ""; } if(substr(afterdrive(targetpath),1,1)!="/") { targetpath = stripdir(base afterdrive(targetpath)); } if(targetpath==base) { return "./" } root = commonroot(targetpath,base); # relpath = relative path to root relpath = ""; while(stripdir(base relpath)!=root) { relpath = relpath "../" } # relative path from root to targetpath fromroot = substr(targetpath,length("" root)+1,length("" targetpath)-length("" root)); relpath = relpath fromroot; return relpath;}function fmain(targetpath,dash,base,limit,sep,varname) { if(targetpath=="") { return ""; } if(dash!="-") { return ""; } targetpath = stripdir(toslash(targetpath,sep)); base = stripdir(toslash(base,sep)); limit = stripdir(toslash(limit,sep)); if(! (sureissubdir(targetpath,limit) && sureissubdir(base,limit)) ) { return ""; } if(varname!="") { varname = "$(" varname ")/" } return varname reldir(targetpath,base);}BEGIN { FS=" ";}{ print striptrailingslash(fmain($1, $2, $3, $4, $5, $6));}'
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?