1

Maybe the question is not clear, here I try to state it in more detail: I have a folder named project, for instance. In it I have two folders, one is named code, the other is named data. In the code folder, I have two code files: one is testCode.nb, the other is testCode.m, these two files always synchronized (have the same contents). What the code does is quite simple, it export a list to a file named test.txt, which I require it to locate in the data folder. How can I achieve this?

If in the code files I have:

lst={{1,Pi},{2,2 Pi}};
SetDirectory["../data"];
Export["test.txt",lst//N,"Table"];

The code run as script .m file in the terminal (on ubuntu linux) pass but failed in notebook. The error is:

SetDirectory::cdir: Cannot set current directory to ../data. >>
an offer can't refuse
  • 1,745
  • 12
  • 23
  • This was asked before. analogue-of-notebookdirectory-for-scripts-to-get-the-directory-path-of-my-scr so once you know current directory of script, you can now do the rest. – Nasser Jan 06 '16 at 03:51
  • @Nasser I don't need to know the current directory of the script. I just need to export the data to the folder data which is one level up to the current code directory, with the same code both in notebook interface and script interface, doing them seperately is easy. Please see my edited question. – an offer can't refuse Jan 06 '16 at 04:30
  • I just need to export the data to the folder data which is one level up to the current code directory I must be missing something. If you can find out the current code directory (which is what the answer linked to shows), then you know the folder above it. So I do not know what is the issue. You also do not have to set directory to save to it. You can just construct the file path. – Nasser Jan 06 '16 at 04:34
  • i.e if can determine that the script directory is c:\my_folder\my_code then the data directory will be c:\my_folder\data. Right? – Nasser Jan 06 '16 at 04:41
  • @Nasser So why can't I using the code in my question in the notebook interface? Using it in script is fine. Why do I have to deal with absolute path? – an offer can't refuse Jan 06 '16 at 04:48
  • When the notebook or script is run, there is a default current directory that is set, which is different from the actual directory where the script or the notebook is located. On windows 7 it says C:\Users\<user_name>\Documents. So you have to correct this to the actual current directory where the notebook or the script is first. Then from there, you can go one level above to the data directory. I do not know where your script is located. May where it is located there happened to already data directory above it so it worked. – Nasser Jan 06 '16 at 04:54
  • again, you do not need to SetDirectory["../data"]; to export to it. Just add the path to the file name. See first if the linked answer works for you. – Nasser Jan 06 '16 at 04:57
  • So, what about my answer, seems to work, you just have to go up one more level since I understood data dir is in Notebook/Script directory. – Kuba Jan 06 '16 at 09:41
  • @Kuba Not exactly, data dir is not in Notebook directory, see my edited question. But your code is very good! Your code seems to say that if we are working in the notebook interface, $Input="". Else if we are working in the terminal, $Input is not equal to "". Right? What is $Input stands for in this case? – an offer can't refuse Jan 06 '16 at 11:57
  • @buzhidao yes, about the edit you can move up one level like: If[$Input === "", FileNameJoin[{ParentDirectory@NotebookDirectory[], "data"}], FileNameJoin[{ParentDirectory@DirectoryName@$InputFileName, "data"}]]. About your second question, take a look at documentation for $Input and $InputFileName, strange that there isn't anything built in which knows but at least we have a way to check ;) – Kuba Jan 06 '16 at 12:02

2 Answers2

2

related: Analogue of NotebookDirectory[] for scripts (to get the directory path of my script.m)?

It's longer, so not so tempting to use what MMA provides but it is encouraged if you want to write OS/environment independent scripts:

If[$Input === "",
 FileNameJoin[{NotebookDirectory[], "data"}],
 FileNameJoin[{DirectoryName @ $InputFileName, "data"}]
 ]
"C:\\ [....] \\data" 
path = FileNameJoin[{$TemporaryDirectory, "test.m"}];

Export[path, "If[$Input === \"\",    
     FileNameJoin[{NotebookDirectory[],\"data\"}],
     FileNameJoin[{DirectoryName@$InputFileName,\"data\"}]
  , "String"]

Get@path
C:\\ [...] \\ Local \\ Temp \\ data

Edit Above answer has assumed data folder is in the same directory as the code files. The code going one level upper and more related to OP's question is like this:

lst={{1,Pi},{2,2 Pi}};

path = FileNameJoin[{ParentDirectory @ #,"data"}]& @ If[ $Input==="", 
    NotebookDirectory[],
 DirectoryName @ $InputFileName
];

path = FileNameJoin[{path,"test.txt"}];

Export[path, lst//N, "Table"];
Kuba
  • 136,707
  • 13
  • 279
  • 740
0
myDir = "dataTest";
If[Length[
    FileNames[
     myDir = FileNameJoin[{$UserDocumentsDirectory, myDir}]]] == 0, 
  CreateDirectory[myDir]];
lst = {{1, Pi}, {2, 2 Pi}};
Export[FileNameJoin[{myDir, "test.txt"}], lst // N, "Table"]
Zviovich
  • 9,308
  • 1
  • 30
  • 52
  • You don't need to creat a new directory, the directory is in name data which is one level upper to the current notebook directory and script directory. All I want is to let the file save to that directory both in notebook interface and script interface. – an offer can't refuse Jan 06 '16 at 03:25
  • @buzhidao, the code was tested to ensure that it works in script mode under windows 10. It can be modified in whatever way you see fit. – Zviovich Jan 06 '16 at 12:23