POKI_PUT_TOC_HERE

<h1>No output at all</h1>

<p/>Check the line-terminators of the data, e.g. with the command-line
<tt>file</tt> program. Example: for CSV, Miller&rsquo;s default line terminator
is CR/LF (carriage return followed by linefeed, following
<a href="https://tools.ietf.org/html/rfc4180">RFC4180</a>). Yet if your CSV has
*nix-standard LF line endings, Miller will keep reading the file looking for a
CR/LF which never appears. Solution in this case: tell Miller the input has LF line-terminator, e.g. <b>mlr --csv --rs
lf {remaining arguments ...}</b>.

<p/>Also try <tt>od -xcv</tt> and/or <tt>cat -e</tt> on your file to check for non-printable characters.

<h1>Fields not selected</h1>

<p/>Check the field-separators of the data, e.g. with the command-line
<tt>head</tt> program. Example: for CSV, Miller&rsquo;s default record
separator is comma; if your data is tab-delimited, e.g. <tt>aTABbTABc</tt>,
then Miller won&rsquo;t find three fields named <tt>a</tt>, <tt>b</tt>, and
<tt>c</tt> but rather just one named <tt>aTABbTABc</tt>.  Solution in this
case: <tt>mlr --fs tab {remaining arguments ...}</tt>.

<p/>Also try <tt>od -xcv</tt> and/or <tt>cat -e</tt> on your file to check for non-printable characters.

<h1>Diagnosing delimiter specifications</h1>

POKI_INCLUDE_ESCAPED(data/delimiter-examples.txt)HERE

<h1>Error-output in certain string cases</h1>

<p/> <tt>mlr put '$y = string($x); $z=$y.$y'</tt> gives <tt>(error)</tt> on
numeric data such as <tt>x=123</tt> while <tt>mlr put
'$z=string($x).string($x)'</tt> does not. This is because in the former case
<tt>y</tt> is computed and stored as a string, then re-parsed as an integer,
for which string-concatenation is an invalid operator.

<h1>How do I examine then-chaining?</h1>

<p/>Then-chaining found in Miller is intended to function the same as Unix
pipes. You can print your data one pipeline step at a time, to see what
intermediate
output at one step becomes the input to the next step.

<p/>First, review the input data:

POKI_RUN_COMMAND{{cat data/then-example.csv}}HERE

Next, run the first step of your command, omitting anything from the first <tt>then</tt> onward:

POKI_RUN_COMMAND{{mlr --icsv --rs lf --opprint count-distinct -f Status,Payment_Type data/then-example.csv}}HERE

After that, run it with the next <tt>then</tt> step included:

POKI_RUN_COMMAND{{mlr --icsv --rs lf --opprint count-distinct -f Status,Payment_Type then sort -nr count data/then-example.csv}}HERE

Now if you include another <tt>then</tt> step after this, the columns <tt>Status</tt>,
<tt>Payment_Type</tt>, and <tt>count</tt> will be its input.

<p/>Note, by the way, that you&rsquo;ll get the same results using pipes:
POKI_RUN_COMMAND{{mlr --csv --rs lf count-distinct -f Status,Payment_Type data/then-example.csv | mlr --icsv --rs lf --opprint sort -nr count}}HERE

<h1>Why doesn&rsquo;t mlr cut put fields in the order I want?</h1>

<p/>Example: columns <tt>x,i,a</tt> were requested but they appear here in the order <tt>a,i,x</tt>:

POKI_RUN_COMMAND{{cat data/small}}HERE
POKI_RUN_COMMAND{{mlr cut -f x,i,a data/small}}HERE

<p/>The issue is that Miller&rsquo;s <tt>cut</tt>, by default, outputs cut fields in the order they
appear in the input data. This design decision was made intentionally to parallel the *nix system <tt>cut</tt>
command, which has the same semantics.

<p/>The solution is to use the <tt>-o</tt> option:

POKI_RUN_COMMAND{{mlr cut -o -f x,i,a data/small}}HERE

<h1>Why am I not seeing all possible joins occur?</h1>

<p/>For example, the right file here has nine records, and the left file should
add in the <tt>hostname</tt> column &mdash; so the join output should also have
9 records:

POKI_RUN_COMMAND{{mlr --icsvlite --opprint cat data/join-u-left.csv}}HERE
POKI_RUN_COMMAND{{mlr --icsvlite --opprint cat data/join-u-right.csv}}HERE
POKI_RUN_COMMAND{{mlr --icsvlite --opprint join -j ipaddr -f data/join-u-left.csv data/join-u-right.csv}}HERE

<p/>The issue is that Miller&rsquo;s <tt>join</tt>, by default, takes input
sorted (lexically ascending) by the sort keys on both the left and right files.
This design decision was made intentionally to parallel the *nix system
<tt>join</tt> command, which has the same semantics. The benefit of this
default is that the joiner program can stream through the left and right files,
needing to load neither entirely into memory. The drawback, of course, is that
is requires sorted input.

<p/>The solution (besides pre-sorting the input files on the join keys) is to
simply use <b>mlr join -u</b>. This loads the left file entirely into memory
(while the right file is still streamed one line at a time) and does all
possible joins without requiring sorted input:

POKI_RUN_COMMAND{{mlr --icsvlite --opprint join -u -j ipaddr -f
data/join-u-left.csv data/join-u-right.csv}}HERE

<p/>General advice is to make sure the left-file is relatively small, e.g.
containing name-to-number mappings, while saving large amounts of data for the
right file.

<h1>What about XML or JSON file formats?</h1>

<p/>Miller handles <boldmaroon>tabular data</boldmaroon>, which is a list of
records each having fields which are key-value pairs. Miller also doesn&rsquo;t
require that each record have the same field names (see also <a
href="record-heterogeneity.html">here</a>). Regardless, tabular data is a
<boldmaroon>non-recursive data structure</boldmaroon>.

<p/> XML, JSON, etc. are, by contrast, all <boldmaroon>recursive</boldmaroon>
or <boldmaroon>nested</boldmaroon> data structures. For example, in JSON
you can represent a hash map whose values are lists of lists.

<p/>Now, you can put tabular data into these formats &mdash; since list-of-key-value-pairs
is one of the things representable in XML or JSON. Example:

<p/>
<div class="pokipanel">
<pre>
# DKVP
x=1,y=2
z=3

# XML
&lt;table&gt;
  &lt;record&gt;
    &lt;field&gt;
      &lt;key&gt; x &lt;/key&gt; &lt;value&gt; 1 &lt;/value&gt;
    &lt;/field&gt;
    &lt;field&gt;
      &lt;key&gt; y &lt;/key&gt; &lt;value&gt; 2 &lt;/value&gt;
    &lt;/field&gt;
  &lt;/record&gt;
    &lt;field&gt;
      &lt;key&gt; z &lt;/key&gt; &lt;value&gt; 3 &lt;/value&gt;
    &lt;/field&gt;
  &lt;record&gt;
  &lt;/record&gt;
&lt;/table&gt;

# JSON
[{"x":1,"y":2},{"z":3}]
</pre>
</div>

<p/>However, a tool like Miller which handles non-recursive data is never going
to be able to handle full XML/JSON semantics &mdash; only a small subset.  If
tabular data represented in XML/JSON/etc are sufficiently well-structured, it
may be easy to grep/sed out the data into a simpler text form &mdash; but this
is a general text-processing problem.

<p/>My preference is to keep Miller doing what it does well, and to leave XML
to XML tools such as <tt>xmllint</tt> and JSON to JSON tools such as
<tt>jq</tt> or <tt>recs</tt>. Putting (necessarily) limited support for these
file formats into Miller seems like a slippery slope wherein inadequate
solutions would be delivered for an inherently unattainable goal.
