docs/src/reference-main-separators.md
Miller has record separators, field separators, and pair separators. For example, given the following DKVP records:
<pre class="pre-highlight-in-pair"> <b>cat data/a.dkvp</b> </pre> <pre class="pre-non-highlight-in-pair"> a=1,b=2,c=3 a=4,b=5,c=6 </pre>, -- it separates fields (key-value pairs) from one another;= -- it separates the key from the value within each key-value pair.These are the default values, which you can override with flags such as --ips
and --ops (below).
Not all file formats have all three of these: for example, CSV does not have a pair separator, since keys are on the header line and values are on each data line.
Also, separators are not programmable for all file formats. For example, in
JSON objects, the pair separator is : and the
field-separator is , -- we write {"a":1,"b":2,"c":3} -- but these aren't
modifiable. If you do mlr --json --ips : --ips '=' cat myfile.json then you
don't get {"a"=1,"b"=2,"c"=3}. This is because the pair-separator : is
part of the JSON specification.
Miller lets you use the same separators for input and output (e.g. CSV input, CSV output), or, to change them between input and output (e.g. CSV input, JSON output), if you wish to transform your data in that way.
Miller uses the names IRS and ORS for the input and output record
separators, IFS and OFS for the input and output field separators, and
IPS and OPS for input and output pair separators.
For example:
<pre class="pre-highlight-in-pair"> <b>cat data/a.dkvp</b> </pre> <pre class="pre-non-highlight-in-pair"> a=1,b=2,c=3 a=4,b=5,c=6 </pre> <pre class="pre-highlight-in-pair"> <b>mlr --ifs , --ofs ';' --ips = --ops : cut -o -f c,a,b data/a.dkvp</b> </pre> <pre class="pre-non-highlight-in-pair"> c:3;a:1;b:2 c:6;a:4;b:5 </pre> <pre class="pre-highlight-in-pair"> <b>mlr --csv head -n 2 example.csv</b> </pre> <pre class="pre-non-highlight-in-pair"> color,shape,flag,k,index,quantity,rate yellow,triangle,true,1,11,43.6498,9.8870 red,square,true,2,15,79.2778,0.0130 </pre> <pre class="pre-highlight-in-pair"> <b>mlr --csv --ofs pipe head -n 2 example.csv</b> </pre> <pre class="pre-non-highlight-in-pair"> color|shape|flag|k|index|quantity|rate yellow|triangle|true|1|11|43.6498|9.8870 red|square|true|2|15|79.2778|0.0130 </pre>If your data has non-default separators and you don't want to change those
between input and output, you can use --rs, --fs, and --ps. Setting --fs : is the same as setting --ifs : --ofs :, but with fewer keystrokes.
All separators can be multi-character, except for file formats which don't
allow parameterization (see below). And for CSV (CSV-lite doesn't have these
restrictions), IRS must be \n and IFS must be a single character.
If your data has field separators which are one or more consecutive spaces, you
can use --ifs space --repifs.
More generally, the --repifs flag means that multiple successive occurrences of the field
separator count as one. For example, in CSV data we often signify nulls by
empty strings, e.g. 2,9,,,,,6,5,4. On the other hand, if the field separator
is a space, it might be more natural to parse 2 4 5 the same as 2 4 5:
--repifs --ifs ' ' lets this happen. In fact, the --ipprint option
is internally implemented in terms of --repifs.
For example:
<pre class="pre-highlight-in-pair"> <b>cat data/extra-spaces.txt</b> </pre> <pre class="pre-non-highlight-in-pair"> oh say can you see by the dawn's early light what so </pre> <pre class="pre-highlight-in-pair"> <b>mlr --ifs ' ' --repifs --inidx --oxtab cat data/extra-spaces.txt</b> </pre> <pre class="pre-non-highlight-in-pair"> 1 oh 2 say 3 can 4 you 1 see 2 by 3 the 4 dawn's 1 early 2 light 3 what 4 so </pre>IFS and IPS can be regular expressions: use --ifs-regex or --ips-regex in place of
--ifs or --ips, respectively.
You can also use either --ifs space --repifs or --ifs-regex '()+'. (But that gets a little tedious,
so there are aliases listed below.) Note however that --ifs space --repifs is about 3x faster than
--ifs-regex '( )+' -- regular expressions are powerful, but slower.
Many things we'd like to write as separators need to be escaped from the shell
-- e.g. --ifs ';' or --ofs '|', and so on. You can use the following if you like:
And for --ifs-regex and --ips-regex:
Note that spaces, tabs, and whitespace already are regexes so you
shouldn't use --repifs with them. (In fact, the --repifs flag is ignored
when --ifs-regex is provided.)
Given the above, we now have seen the following flags:
<pre class="pre-non-highlight-non-pair"> --rs --irs --ors --fs --ifs --ofs --repifs --ifs-regex --ps --ips --ops --ips-regex </pre>See also the separator-flags section.
Miller exposes for you read-only built-in variables with
names IRS, ORS, IFS, OFS, IPS, and OPS. Unlike in AWK, you can't set these in begin-blocks --
their values indicate what you specified at the command line -- so their use is limited.
Notes:
x=1,y=2 and the next has x=3,y=4, and OFS is newline, then output lines are x 1, then y 2, then an extra newline, then x 3, then y 4. This means: to customize XTAB, set OFS rather than ORS.| RS | FS | PS | |
|---|---|---|---|
| CSV | Always \n; not alterable * | Default ,; must be single-character | None |
| TSV | Always \n; not alterable * | Default \t; must be single-character | None |
| CSV-lite | Default \n * | Default , | None |
| TSV-lite | Default \n * | Default \t | None |
| JSON | N/A; records are between { and } | Always ,; not alterable | Always :; not alterable |
| YAML | N/A; documents separated by --- or single array | N/A; not alterable | Always :; not alterable |
| DCF | N/A; paragraphs separated by blank lines | N/A; not alterable | Always :; not alterable |
| DKVP | Default \n | Default , | Default = |
| DKVPX | Default \n | Default , | Default = |
| NIDX | Default \n | Default space | None |
| XTAB | Not used; records are separated by an extra FS | \n * | Default: space with repeats |
| PPRINT | Default \n * | Space with repeats | None |
| Markdown | Always \n; not alterable * | One or more spaces, then ` | `, then one or more spaces; not alterable |
* or \r\n on Windows