32
$\begingroup$

I cannot find how to use relative paths in Mathematica. My directory structure is simple.

Import["G:\\Research\\Acc and Vel Runs\\5-24\\Mathematica\\Data\\250 \
Acc.xls"][[1]] // TableForm  

That demonstrates the absolute path by using the insert path from the menus. I want this notebook to be portable. I want to give someone the "Mathematica" directory and I want them to be able to run the code. I don't want the paths to break because It will be run on a different machine. Basically I just want to use a relative path starting at the Mathematica level shown above.

$\endgroup$

4 Answers 4

44
$\begingroup$

If your notebook is in the top directory, you can use

Import[FileNameJoin[{NotebookDirectory[], "path", "to", "your", "file.xls"}]]

where the string is the relative path from that directory.

If your notebook is elsewhere in the directory tree and you want to set paths relative to a different directory, then you could define a global $ParentDirectory and then use all paths relative to that by joining strings as in the above example. Then all that the other person needs to do is to set this global value once and they're good. For example:

$ParentDirectory = FileNameJoin[{"absolute", "path", "to", "mathematica"}];
Import[FileNameJoin[{$ParentDirectory, "path", "to", "your", "file.xls"}]

As Albert Retey points out, you can also use ParentDirectory[NotebookDirectory[]] to give you the parent directory of the notebook's directory. In other words, it is an equivalent of cd .. from that directory and can be nested as many times as required.

$\endgroup$
6
  • $\begingroup$ This is exactly what I wanted. But your second suggestion with the "ParentDirectory" is interesting but I don't quite understand it. Could you possibly provide a little more explanation? Isn't the "ParentDirectory" an absolute path? PS I will accept your answer as soon as the timer allows $\endgroup$ May 24, 2012 at 23:04
  • $\begingroup$ It is an absolute path. The way you use it is you set $ParentDirectory once and use relative paths from there onwards. When you give it to someone, they set that variable once at the beginning of the notebook/session (or in an init.m file) to what they want it to be and it all works fine. The usage is similar to how Mathematica uses $UserBaseDirectory, $InstallationDirectory, etc. for its stuff. It's hardcoded somewhere, but you can easily change it. This is only in the case where you want to use a different directory than NotebookDirectory[]. If that works, then it's the simplest. $\endgroup$
    – rm -rf
    May 24, 2012 at 23:12
  • $\begingroup$ @MatthewKemnetz This works? I guess I'm a bit surprised, since (judging from the path separators) your operating system appears to be Windows, while R.M.'s appears to be Unix or Mac. The system independent way to do this is with FileNameJoin, as in FileNameJoin[{NotebookDirectory[],"file"}] $\endgroup$ May 25, 2012 at 0:38
  • $\begingroup$ @MarkMcClure I just presented this as an example, and I guess the OP changed it according to their OS. Your point is valid though, as others might not be so careful. I'll add the OS independent way to my answer... $\endgroup$
    – rm -rf
    May 25, 2012 at 0:42
  • 2
    $\begingroup$ @R.M.: you might want to add DirectoryName[NotebookDirectory[]] as a possibility to construct something relative to the current notebook but not necessarily in the "top" directory. Of course that can be Nested as many times as you need... $\endgroup$ May 26, 2012 at 16:56
12
$\begingroup$

Since FileNameJoin was only introduced in Mathematica v7, I thought I'd add a solution using ToFileName for people still running earlier versions (like me):

Import[ToFileName[{
  NotebookDirectory[], "path", "to", "directory"},
  "file.xls"]]

So it works in a similar way, but notice that while the path to the file is enclosed in the {...}, the actual file goes separately.

$\endgroup$
9
$\begingroup$

I realise that this is an old question but I think the following option should also be considered:

SetDirectory[NotebookDirectory[]];

Adding this line at the beginning of your notebook will essentially tell Import to look for your file in a path relative to where your notebook is saved. This method obviously only works after the notebook has been saved!

$\endgroup$
4
$\begingroup$

There is a simple way.

SetDirectory[NotebookDirectory[]]

Then you may give the path as a relative directory:

Import["subdir/file.xls"]

...or involve parent directories:

Import["../path/to/your/file.xls"]

This is much more concise than having to use FileNameJoin, etc, as in other answers. And forward slashes will work, even on Windows. I think they look cleaner than double back slashes.

@lucian's answer helped

$\endgroup$
2
  • 1
    $\begingroup$ Seems to duplicate earlier answer. $\endgroup$
    – bbgodfrey
    Feb 26, 2017 at 5:23
  • $\begingroup$ It appears to me that your answer intends to build upon or clarify an earlier one. It is best in such cases to acknowledge the existing answer before proceeding with your own. Thank you for at least mentioning lucian's answer in an edit. $\endgroup$
    – Mr.Wizard
    Feb 26, 2017 at 14:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.