mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-28 10:13:59 +00:00
single-quoting faqent
This commit is contained in:
parent
f493593699
commit
a528350849
5 changed files with 163 additions and 8 deletions
|
|
@ -3,7 +3,8 @@
|
|||
#include "input/mlr_json_adapter.h"
|
||||
|
||||
static lrec_t* validate_millerable_object(json_value_t* pjson_object, char* flatten_sep, int json_skip_arrays_on_input);
|
||||
static void populate_from_nested_object(lrec_t* prec, json_value_t* pjson_object, char* prefix, char* flatten_sep);
|
||||
static void populate_from_nested_object(lrec_t* prec, json_value_t* pjson_object, char* prefix, char* flatten_sep,
|
||||
int json_skip_arrays_on_input);
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
int reference_json_objects_as_lrecs(sllv_t* precords, json_value_t* ptop_level_json, char* flatten_sep,
|
||||
|
|
@ -65,7 +66,7 @@ lrec_t* validate_millerable_object(json_value_t* pjson, char* flatten_sep, int j
|
|||
case JSON_OBJECT:
|
||||
// This could be made more efficient ... the string length is in the json_value_t.
|
||||
prefix = mlr_paste_2_strings(key, flatten_sep);
|
||||
populate_from_nested_object(prec, pjson_value, prefix, flatten_sep);
|
||||
populate_from_nested_object(prec, pjson_value, prefix, flatten_sep, json_skip_arrays_on_input);
|
||||
free(prefix);
|
||||
break;
|
||||
case JSON_ARRAY:
|
||||
|
|
@ -104,7 +105,10 @@ lrec_t* validate_millerable_object(json_value_t* pjson, char* flatten_sep, int j
|
|||
// Example: the JSON object has { "a": { "b" : 1, "c" : 2 } }. Then we add "a:b" => "1" and "a:c" => "2"
|
||||
// to the lrec.
|
||||
|
||||
static void populate_from_nested_object(lrec_t* prec, json_value_t* pjson_object, char* prefix, char* flatten_sep) {
|
||||
// xxx retval
|
||||
static void populate_from_nested_object(lrec_t* prec, json_value_t* pjson_object, char* prefix, char* flatten_sep,
|
||||
int json_skip_arrays_on_input)
|
||||
{
|
||||
int n = pjson_object->u.object.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
json_object_entry_t* pobject_entry = &pjson_object->u.object.p.values[i];
|
||||
|
|
@ -128,14 +132,69 @@ static void populate_from_nested_object(lrec_t* prec, json_value_t* pjson_object
|
|||
break;
|
||||
case JSON_OBJECT:
|
||||
prefix = mlr_paste_2_strings(lrec_key, flatten_sep);
|
||||
populate_from_nested_object(prec, pjson_value, prefix, flatten_sep);
|
||||
populate_from_nested_object(prec, pjson_value, prefix, flatten_sep, json_skip_arrays_on_input);
|
||||
free(prefix);
|
||||
free(lrec_key);
|
||||
break;
|
||||
case JSON_ARRAY:
|
||||
fprintf(stderr,
|
||||
"%s: found array item within JSON object. This is valid but unmillerable JSON.\n",
|
||||
MLR_GLOBALS.bargv0);
|
||||
if (!json_skip_arrays_on_input) {
|
||||
fprintf(stderr,
|
||||
"%s: found array item within JSON object. This is valid but unmillerable JSON.\n",
|
||||
MLR_GLOBALS.bargv0);
|
||||
}
|
||||
break;
|
||||
case JSON_INTEGER:
|
||||
lrec_put(prec, lrec_key, pjson_value->u.integer.sval, FREE_ENTRY_KEY);
|
||||
break;
|
||||
case JSON_DOUBLE:
|
||||
lrec_put(prec, lrec_key, pjson_value->u.dbl.sval, FREE_ENTRY_KEY);
|
||||
break;
|
||||
default:
|
||||
MLR_INTERNAL_CODING_ERROR();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// xxx retval
|
||||
/*xxx temp static*/
|
||||
void populate_from_nested_array(lrec_t* prec, json_value_t* pjson_array, char* prefix, char* flatten_sep,
|
||||
int json_skip_arrays_on_input)
|
||||
{
|
||||
int n = pjson_array->u.array.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
json_value_t* pjson_value = &pjson_array->u.array.p.values[i];
|
||||
// xxx char* json_key = (char*)pobject_entry->name;
|
||||
char* json_key = "temp"; // xxx temp
|
||||
char* lrec_key = mlr_paste_2_strings(prefix, json_key);
|
||||
char* prefix = NULL;
|
||||
|
||||
switch (pjson_value->type) {
|
||||
case JSON_NONE:
|
||||
lrec_put(prec, lrec_key, "", FREE_ENTRY_KEY);
|
||||
break;
|
||||
case JSON_NULL:
|
||||
lrec_put(prec, lrec_key, "", FREE_ENTRY_KEY);
|
||||
break;
|
||||
case JSON_STRING:
|
||||
lrec_put(prec, lrec_key, pjson_value->u.string.ptr, FREE_ENTRY_KEY);
|
||||
break;
|
||||
case JSON_BOOLEAN:
|
||||
lrec_put(prec, lrec_key, pjson_value->u.boolean.sval, FREE_ENTRY_KEY);
|
||||
break;
|
||||
case JSON_OBJECT:
|
||||
prefix = mlr_paste_2_strings(lrec_key, flatten_sep);
|
||||
populate_from_nested_object(prec, pjson_value, prefix, flatten_sep, json_skip_arrays_on_input);
|
||||
free(prefix);
|
||||
free(lrec_key);
|
||||
break;
|
||||
case JSON_ARRAY:
|
||||
if (!json_skip_arrays_on_input) {
|
||||
fprintf(stderr,
|
||||
"%s: found array item within JSON object. This is valid but unmillerable JSON.\n",
|
||||
MLR_GLOBALS.bargv0);
|
||||
}
|
||||
break;
|
||||
case JSON_INTEGER:
|
||||
lrec_put(prec, lrec_key, pjson_value->u.integer.sval, FREE_ENTRY_KEY);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ BUGFIXES
|
|||
|
||||
! windows port
|
||||
|
||||
! eddelbuettel ac error <-> smith aclocal-1.15?
|
||||
* eddelbuettel ac error <-> smith aclocal-1.15?
|
||||
|
||||
* --mmap / --no-mmap double-regression loop
|
||||
o also "." the setup funcs
|
||||
|
|
|
|||
|
|
@ -85,6 +85,43 @@ POKI_RUN_COMMAND{{echo x,y,z | mlr --dkvp rename 2,999}}HERE
|
|||
POKI_RUN_COMMAND{{echo x,y,z | mlr --dkvp rename 2,newname}}HERE
|
||||
POKI_RUN_COMMAND{{echo x,y,z | mlr --csv --implicit-csv-header reorder -f 3,1,2}}HERE
|
||||
|
||||
</div>
|
||||
<h1>How can I put single-quotes into strings?</h1>
|
||||
<button style="font-weight:bold;color:maroon;border:0" padding=0 onclick="toggle_by_name('section_toggle_single_quotes_in_strings');" href="javascript:;">Toggle section visibility</button>
|
||||
<div id="section_toggle_single_quotes_in_strings" style="display: block">
|
||||
|
||||
<p/> This is a little tricky due to the shell’s handling of quotes. For simplicity, let’s first put
|
||||
an update script into a file:
|
||||
|
||||
POKI_INCLUDE_ESCAPED(data/single-quote-example.mlr)HERE
|
||||
|
||||
POKI_RUN_COMMAND{{echo a=bcd | mlr put -f data/single-quote-example.mlr}}HERE
|
||||
|
||||
<p/>So, it&rsuoq;s simple: Miller’s DSL uses double quotes for strings,
|
||||
and you can put single quotes (or backslash-escaped double-quotes) inside
|
||||
strings, no problem.
|
||||
|
||||
<p/> Without putting the update expression in a file, it’s messier:
|
||||
|
||||
POKI_RUN_COMMAND{{echo a=bcd | mlr put '$a="It'\''s OK, I said, '\''for now'\''."'}}HERE
|
||||
|
||||
<p/> The idea is that the outermost single-quotes are to protect the
|
||||
<tt>put</tt> expression from the shell, and the double quotes within them are
|
||||
for Miller. To get a single quote in the middle there, you need to actually put it <i>outside</i> the single-quoting
|
||||
for the shell. The pieces are
|
||||
|
||||
<ul>
|
||||
<li/> <tt>$a="It</tt>
|
||||
<li/> <tt>\'</tt>
|
||||
<li/> <tt>s OK, I said,</tt>
|
||||
<li/> <tt>\'</tt>
|
||||
<li/> <tt>for now</tt>
|
||||
<li/> <tt>\'</tt>
|
||||
<li/> <tt>.</tt>
|
||||
</ul>
|
||||
|
||||
all concatenated together.
|
||||
|
||||
</div>
|
||||
<h1>Why doesn’t mlr cut put fields in the order I want?</h1>
|
||||
<button style="font-weight:bold;color:maroon;border:0" padding=0 onclick="toggle_by_name('section_toggle_cut_out_of_order');" href="javascript:;">Toggle section visibility</button>
|
||||
|
|
|
|||
1
doc/data/single-quote-example.mlr
Normal file
1
doc/data/single-quote-example.mlr
Normal file
|
|
@ -0,0 +1 @@
|
|||
$a = "It's OK, I said, then 'for now'."
|
||||
58
doc/faq.html
58
doc/faq.html
|
|
@ -192,6 +192,7 @@ Miller commands were run with pretty-print-tabular output format.
|
|||
• <a href="#Diagnosing_delimiter_specifications">Diagnosing delimiter specifications</a><br/>
|
||||
• <a href="#How_do_I_examine_then-chaining?">How do I examine then-chaining?</a><br/>
|
||||
• <a href="#I_assigned_$9_and_it’s_not_9th">I assigned $9 and it’s not 9th</a><br/>
|
||||
• <a href="#How_can_I_put_single-quotes_into_strings?">How can I put single-quotes into strings?</a><br/>
|
||||
• <a href="#Why_doesn’t_mlr_cut_put_fields_in_the_order_I_want?">Why doesn’t mlr cut put fields in the order I want?</a><br/>
|
||||
• <a href="#NR_is_not_consecutive_after_then-chaining">NR is not consecutive after then-chaining</a><br/>
|
||||
• <a href="#Why_am_I_not_seeing_all_possible_joins_occur?">Why am I not seeing all possible joins occur?</a><br/>
|
||||
|
|
@ -442,6 +443,63 @@ z,x,y
|
|||
</div>
|
||||
<p/>
|
||||
|
||||
</div>
|
||||
<a id="How_can_I_put_single-quotes_into_strings?"/><h1>How can I put single-quotes into strings?</h1>
|
||||
<button style="font-weight:bold;color:maroon;border:0" padding=0 onclick="toggle_by_name('section_toggle_single_quotes_in_strings');" href="javascript:;">Toggle section visibility</button>
|
||||
<div id="section_toggle_single_quotes_in_strings" style="display: block">
|
||||
|
||||
<p/> This is a little tricky due to the shell’s handling of quotes. For simplicity, let’s first put
|
||||
an update script into a file:
|
||||
|
||||
<p/>
|
||||
<div class="pokipanel">
|
||||
<pre>
|
||||
$a = "It's OK, I said, then 'for now'."
|
||||
</pre>
|
||||
</div>
|
||||
<p/>
|
||||
|
||||
<p/>
|
||||
<div class="pokipanel">
|
||||
<pre>
|
||||
$ echo a=bcd | mlr put -f data/single-quote-example.mlr
|
||||
a=It's OK, I said, then 'for now'.
|
||||
</pre>
|
||||
</div>
|
||||
<p/>
|
||||
|
||||
<p/>So, it&rsuoq;s simple: Miller’s DSL uses double quotes for strings,
|
||||
and you can put single quotes (or backslash-escaped double-quotes) inside
|
||||
strings, no problem.
|
||||
|
||||
<p/> Without putting the update expression in a file, it’s messier:
|
||||
|
||||
<p/>
|
||||
<div class="pokipanel">
|
||||
<pre>
|
||||
$ echo a=bcd | mlr put '$a="It'\''s OK, I said, '\''for now'\''."'
|
||||
a=It's OK, I said, 'for now'.
|
||||
</pre>
|
||||
</div>
|
||||
<p/>
|
||||
|
||||
<p/> The idea is that the outermost single-quotes are to protect the
|
||||
<tt>put</tt> expression from the shell, and the double quotes within them are
|
||||
for Miller. To get a single quote in the middle there, you need to actually put it <i>outside</i> the single-quoting
|
||||
for the shell. The pieces are
|
||||
|
||||
<ul>
|
||||
<li/> <tt>$a="It</tt>
|
||||
<li/> <tt>\'</tt>
|
||||
<li/> <tt>s OK, I said,</tt>
|
||||
<li/> <tt>\'</tt>
|
||||
<li/> <tt>for now</tt>
|
||||
<li/> <tt>\'</tt>
|
||||
<li/> <tt>.</tt>
|
||||
</ul>
|
||||
|
||||
all concatenated together.
|
||||
|
||||
</div>
|
||||
<a id="Why_doesn’t_mlr_cut_put_fields_in_the_order_I_want?"/><h1>Why doesn’t mlr cut put fields in the order I want?</h1>
|
||||
<button style="font-weight:bold;color:maroon;border:0" padding=0 onclick="toggle_by_name('section_toggle_cut_out_of_order');" href="javascript:;">Toggle section visibility</button>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue