Version 50 of file join

Updated 2013-04-18 00:29:53 by pooryorick

Summary

[file join] joins together elements to form a file path

See Also

file
file separator
file split
Tilde Substitution

Synopsis

file join name ?name ...?

Documentation

man page

Description

[file join] joins zero or more strings using the correct platform-dependent separators so that the result can be interpreted as a path name. If a particular name is relative, then it will be joined to the previous file name argument. Any argument that is an absolute path causes all previous arguments to be discarded, and any additional arguments will then be joined to it. For example,

file join a b /foo bar

returns

/foo/bar

Note that any of the names can contain separators, and that the result is always canonical for the current platform: / for Unix and Windows, and : for pre-OSX Macintosh.

[file join] does not join items in lists. If a list contains path elements to be joined, use Argument expansion:

file join {*}[file split a/b/c]

If the {*} operator is not available in your version of Tcl, and it isn't feasible to upgrade, see [eval for the proper way to use [[eval] to expand a list.

Another example:

set path a/b/c/d/e/f/g; set common_length 3
set path [file join {*}[lrange [file split $path] $common_length end]]

Or, ror historic versions of Tcl without the {*} operator:

set path a/b/c/d/e/f/g; set common_length 3
set script {file join}
set script [concat $script [lrange [file split $path] $common_length end]]
set path [eval $script]
puts $path

One reaon [[file join] doesn't join list elements is that its behaviour would then be incorrect in the following case:

#warning: bad code ahead!
file join "C:/Program Files/Tcl"

The [[pwd] Trick

One way to convert a file type from (possibly) relative to absolute is this:

set filename [file join [pwd] $filename]

DKF: Note that you never need to use [[cd], and it is best if you don't except in response to user action. Otherwise you just confuse your users... :^/

Using [file join] to Normalize Path Separators

[file join] can be used to "normalize" the path separators for relative paths that you don't want to subject to the full [[file normalize]:

% file join {\foo\bar\grill}
/foo/bar/grill

Back the other way with file nativename:

% file nativename /foo/bar/grill
\foo\bar\grill

Escaping Tilde Substitution

To join a file whose name begins with "~" (tilde), prefix it with "./":

file join pwd ./~filename.ext

See Tilde Substitution