# How to import .txt file with missing data?

I have a .txt file that looks like this (direct copy from the file):

8.1376   7.2490    6.4005                   3.3893e-06 5.4310e-06 1.7980e-05 1.5303e-05
11.2834  10.1948   8.1657   32.256   68.032 3.2509e-06 3.9237e-06 8.0432e-06 5.3961e-06
1.5350   1.1260    0.8500                   6.6665e-07 6.8028e-07 1.9302e-06 2.4867e-06
0.9850   0.6920    0.2360    0.192    0.768 3.3890e-09 9.8610e-09 4.6064e-08 1.3044e-07
1.5820   1.1040    0.9130   35.712   67.840 3.2341e-07 3.7886e-07 2.4787e-06 2.9939e-06


I'm interested in the 5th column, in which there are some missing data in some rows. When I just

Import["file.txt", "Table"]


MMA does not see the empty positions, so e.g. the first row has 7 elements, and the 5th becomes 5.4310e-06, which is not what I want.

How can I import the data with proper structure, and extract the desired column?

str = Import["file.txt", "Data"];
mat = StringSplit[
StringReplace[str, {"         " -> " {}", "e" -> "*^"}],
WhitespaceCharacter ..
] // ToExpression;
mat// MatrixForm


• The "Data" import format is undocumented, not listed in \$ImportFormats. The documented (and probably faster) way to do the same is to use ReadList["test.txt", String]. Jun 11 '19 at 17:20
• Interesting! Thanks for the information. Jun 11 '19 at 17:30
• @AlexeyPopkov "Data" is not a format, if you do Import["foo", "Data"] it is the "Data" element from FileFormat["foo"] Jun 14 '19 at 17:47

From your example it seems that the stringlength of a number can't be more than 10, so any number consists from 1 to 10 characters (digits, "e" character and the dot "."). Existing numbers can be separated by from one to 10 whitespaces on one line. And the last number can have no whitespace at the end. So we need to preprocess:

str="8.1376   7.2490    6.4005                   3.3893e-06 5.4310e-06 1.7980e-05 1.5303e-05
11.2834  10.1948   8.1657   32.256   68.032 3.2509e-06 3.9237e-06 8.0432e-06 5.3961e-06
1.5350   1.1260    0.8500                   6.6665e-07 6.8028e-07 1.9302e-06 2.4867e-06
0.9850   0.6920    0.2360    0.192    0.768 3.3890e-09 9.8610e-09 4.6064e-08 1.3044e-07
1.5820   1.1040    0.9130   35.712   67.840 3.2341e-07 3.7886e-07 2.4787e-06 2.9939e-06";

lines=StringSplit[StringReplace[str,{EndOfLine->" ","e"->"*^"}],"\r\n"|"\n"];
matrixOfStrings=StringCases[lines,Repeated[Except[" "],{0,11}]~~Repeated[" ",{1,9}]];
matrix=ToExpression[matrixOfStrings,InputForm];
%//TableForm


UPDATE

Another method which allows the columns to have arbitrary width:

str = ReadList["test.txt", String];

Transpose[Transpose[
PadRight[Characters[str], Automatic, " "]] /. {c : {" " ..} :> Table["\t", Length[c]]
, "e" -> "*^"}]
ToExpression[StringJoin /@ DeleteCases[SplitBy[#, # === "\t" &], {"\t" ..}] & /@ %]
MatrixForm@%


(output is the same)

• And how to do it from a file? I.e., how to Import["file.txt"] to obtain your str? Jun 11 '19 at 16:49
• @corey Use str=Import["file.txt","String"]. Note that on Windows in my code you may be should replace "\n" with "\r\n". Jun 11 '19 at 16:51
• @corey979 I've updated the answer so it should work both under Windows and Linux. Jun 11 '19 at 16:56