4
$\begingroup$

I would like to open the file "myfile.cdf" or "myfile.nb". One or the other will be in the directory but not both. Because I don't know which, I'm trying to use StringExpression to be general about opening the file. Here is the code below. It does't seem to work. Ideas?

NotebookOpen[NotebookDirectory[]<>"myfile." ~~ __]
$\endgroup$
1
  • $\begingroup$ That did It! Thank you. $\endgroup$
    – B flat
    Commented Jul 24, 2017 at 0:43

3 Answers 3

4
$\begingroup$
NotebookOpen[First@FileNames[NotebookDirectory[] <> "myfile.*"]]
$\endgroup$
1
  • $\begingroup$ Thank you. Been away from Mathematica for awhile. I can't believe I forgot this. $\endgroup$
    – B flat
    Commented Jul 23, 2017 at 20:57
2
$\begingroup$

This seems to be reasonably robust. You can even use wildcard * in the name string, but in that case you will open the file which is 1st match in the list returned by FileNames.

openNBorCDF[name_String] :=
  Module[{pathNames, file},
    pathNames =
      FileNames[{name <> ".nb", name <> ".cdf"}, NotebookDirectory[]];
    file = First[pathNames, Return[$Failed]];
    NotebookOpen[file];
    file]

On my system, evaluating

openNBorCDF["test"]

in a notebook loaded from the Desktop directory opens test.cdf and returns

"/Users/oldmg/Desktop/test.cdf"

while evaluating

openNBorCDF["foo"]

opens nothing and returns

$Failed

because neither foo.nb nor foo.cdf exists in my Desktop directory.

Edit

The above code requires V10.3 or later. Those with earlier versions of Mathematica should try this:

openNBorCDF[name_String] :=
  Module[{pathNames, file},
   pathNames =
     FileNames[{name <> ".nb", name <> ".cdf"}, NotebookDirectory[]];
   If[pathNames === {}, Return[$Failed], file = pathNames[[1]]];
   NotebookOpen[file];
   file]
$\endgroup$
1
  • $\begingroup$ @MichaelMcCain. I used a form of First that only became available in V10.3. Are you using an earlier version? $\endgroup$
    – m_goldberg
    Commented Jul 24, 2017 at 0:23
2
$\begingroup$

StringExpression, like all patterns, are template which can be matched against. They don't automagically expand to match eveything--you do some function to do that. I'd write your code like this

NotebookOpen[First[FileNames[NotebookDirectory[] <> "test." <> # & /@ {"cdf", "pdf"}]]]

This will give you a list of the 0, 1 or 2, files which match the two names, and no others. Of course, it will error if there are no matches (which you'll need to handle), but this also allows you to control which of the two files to prefer if both are present, just be reordering the list of extensions.


Expansion: Since the first thing I wrote had so many typos, here's a bonus answer based on the same idea, which is probably how I'd write this. The code to find the files is the same, but rather than naively taking First, I use Replace. If the result is a list of one or more file names, I open the first one (which will return a NotebookObject pointing to what was just opened). Otherwise, I return $Failed. The code following the assignment can check result and decide what to do...

result = Replace[
   FileNames[NotebookDirectory[] <> "myfile." <> # & /@ {"cdf", "nb"}],
   {
      {file_String, ___} :> NotebookOpen[file],
      _ -> $Failed
   }
]
$\endgroup$
5
  • 1
    $\begingroup$ Missing /@ in between the function and the list. $\endgroup$
    – C. E.
    Commented Jul 23, 2017 at 22:00
  • $\begingroup$ Also, too many periods in file file paths generated; e.g., 'myfile..nb' $\endgroup$
    – m_goldberg
    Commented Jul 23, 2017 at 22:32
  • 1
    $\begingroup$ You should test your code before you post it. $\endgroup$
    – m_goldberg
    Commented Jul 23, 2017 at 22:32
  • $\begingroup$ Yes. I can't seem to get this code to work even with the changes. $\endgroup$
    – B flat
    Commented Jul 23, 2017 at 23:46
  • $\begingroup$ Note sure what I pasted in there, because it certainly wasn't right (and I did test the code, only I used files I actually have on my filesystem). This code show now work. $\endgroup$ Commented Jul 24, 2017 at 3:53

Your Answer

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

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