1
$\begingroup$

The following question is related to this one.

I have as example this list:

{{15, 0, 0, 69, 250}, {15, 0, 0, 88, 121}, {15, 0, 0, 107, 248}, 
{15, 0, 0, 125, 119}, {15, 0, 0, 144, 246}, {15, 0, 0, 163, 117},
{15, 0, 0, 181, 244}, {15, 0, 0, 200, 115}, {15, 0, 0, 219, 242}, 
{15, 0, 0, 237, 113}};

I would like to open a file for writing and then write the data right aligned line by line in a loop (not at once with Export) to the file. Finally the file should be closed.

The content of the file should be:

15    0    0     69    250
15    0    0     88    121
15    0    0    107    248
15    0    0    125    119
15    0    0    144    246
15    0    0    163    117
15    0    0    181    244
15    0    0    200    115
15    0    0    219    242
15    0    0    237    113

I tried the following:

list = {{15, 0, 0, 69, 250}, {15, 0, 0, 88, 121}, {15, 0, 0, 107, 248}, 
        {15, 0, 0, 125, 119}, {15, 0, 0, 144, 246}, {15, 0, 0, 163, 117},
        {15, 0, 0, 181, 244}, {15, 0, 0, 200, 115}, {15, 0, 0, 219, 242}, 
        {15, 0, 0, 237, 113}};

n = Length[list];

file = OpenWrite["d:\\output.txt"];

Do[
  Write[file, list[[i]]];
  , {i, 1, n}
  ];

Close[file];

The text content is not right aligned and containes curly braces and commas:

{15, 0, 0, 69, 250}
{15, 0, 0, 88, 121}
{15, 0, 0, 107, 248}
{15, 0, 0, 125, 119}
{15, 0, 0, 144, 246}
{15, 0, 0, 163, 117}
{15, 0, 0, 181, 244}
{15, 0, 0, 200, 115}
{15, 0, 0, 219, 242}
{15, 0, 0, 237, 113}
$\endgroup$
6
  • 1
    $\begingroup$ If you're willing to preprocess with a combination of StringPadLeft and StringJoin to construct each line you could do this relatively painlessly with WriteString. $\endgroup$
    – b3m2a1
    Mar 14 '17 at 15:02
  • $\begingroup$ @MB1965: Could you please show it a short answer? $\endgroup$
    – mrz
    Mar 14 '17 at 15:06
  • 2
    $\begingroup$ Possible duplicate of Formatting output of OpenAppend[] to match what Export[data,file,".csv"] would output? $\endgroup$
    – Szabolcs
    Mar 14 '17 at 15:07
  • 1
    $\begingroup$ You can write to a stream using Export. Or you can ExportString, then WriteString the result to the stream. The purpose of Export/ExportString here is to create the desired formatting. $\endgroup$
    – Szabolcs
    Mar 14 '17 at 15:09
  • 1
    $\begingroup$ @Szabolcs I think it depends on the formatting desired. Since the OP wants to do it line-by-line if a tab would suffice ExportString[ line, "TSV" ] should work, but otherwise the justification needs to be done by hand I think. $\endgroup$
    – b3m2a1
    Mar 14 '17 at 15:14
2
$\begingroup$

So depending on whether tab separation is sufficient or not there are two approaches.

First is the basic string-it-all-together approach:

With[{file = 
    OpenWrite@FileNameJoin@{$TemporaryDirectory, "output.txt"}},

  Do[

   WriteLine[
    file,
    StringPadLeft[ToString@#, 6] & /@ d // StringTrim@*StringJoin
    ],
   {d, data}
   ];

  Close@file
  ] // Import

Alternatively if you can deal with tabs as your separators, not enforcing some width-convention (I think this is probably the more common case):

With[{file = 
   OpenWrite@FileNameJoin@{$TemporaryDirectory, "output.txt"}},

 Do[
  WriteLine[file,
   ExportString[
    {d},
    "TSV"
    ]
   ],
  {d, data}
  ];

 Close@file
 ]

I would generally prefer the second, myself, as the more I can stick with what WRI provides the easier my life tends to be.

$\endgroup$
5
  • $\begingroup$ Great. Is it possible to align the numbers to right in each column? $\endgroup$
    – mrz
    Mar 14 '17 at 15:26
  • 1
    $\begingroup$ Yeah, replace StringPadRight with StringPadLeft should do it. And then put StringTrim@* in front of StringJoin. $\endgroup$
    – b3m2a1
    Mar 14 '17 at 15:27
  • $\begingroup$ @mrz edited the answer to reflect that. $\endgroup$
    – b3m2a1
    Mar 14 '17 at 15:29
  • $\begingroup$ The first code works great. The second is left aligned. $\endgroup$
    – mrz
    Mar 14 '17 at 15:39
  • 1
    $\begingroup$ @mrz I didn't change the second at all. Not sure there's a way to do left-aligned with tabs without specifying that at the text-editor level or something. $\endgroup$
    – b3m2a1
    Mar 14 '17 at 15:44
0
$\begingroup$

Another possibility:

list = {{15, 0, 0, 69, 250}, {15, 0, 0, 88, 121}, {15, 0, 0, 107, 248},
        {15, 0, 0, 125, 119}, {15, 0, 0, 144, 246}, {15, 0, 0, 163, 117},
        {15, 0, 0, 181, 244}, {15, 0, 0, 200, 115}, {15, 0, 0, 219, 242},
        {15, 0, 0, 237, 113}};

n = Length[list];

file = OpenWrite@FileNameJoin@{$TemporaryDirectory, "output.txt"};

Do[

  outputline = StringJoin[
                ToString[
                 PaddedForm[#, 3, NumberPadding -> {" ", ""}]] & /@ list[[i]
                ]
               ];

  WriteLine[file, outputline];

  , {i, 1, n}

  ];

Close[file] // Import


  15   0   0  69 250
  15   0   0  88 121
  15   0   0 107 248
  15   0   0 125 119
  15   0   0 144 246
  15   0   0 163 117
  15   0   0 181 244
  15   0   0 200 115
  15   0   0 219 242
  15   0   0 237 113
$\endgroup$
1
  • 1
    $\begingroup$ There's also another form that routes through ExportString but I forgot to add it to my answer. $\endgroup$
    – b3m2a1
    Mar 15 '17 at 21:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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