[anon] add an anonymizer to help with support requests

Fixes #1055
pull/1062/head
Tim Stack 2 years ago
parent fadcea4403
commit eb0bd4ac9a

@ -7,6 +7,15 @@ lnav v0.11.1:
- Each regex must have a corresponding sample log message - Each regex must have a corresponding sample log message
that it matches. that it matches.
- Each sample must be matched by only one regex. - Each sample must be matched by only one regex.
* Added built-in support for anonymizing content. The
`:write-*` commands now accept an `--anonymize` option
and there is an `anonymize()` SQL function. The
anonymization process will try to replace identifying
information with random data. For example, IPv4 addresses
are replaced with addresses in the 10.0.0.0/8 range.
(This feature is mainly intended to help with providing
information to lnav support that does not have sensitive
values.)
Breaking changes: Breaking changes:
* The regexp_capture() table-valued-function now returns NULL * The regexp_capture() table-valued-function now returns NULL

@ -76,6 +76,56 @@ an error message in the status bar, like so:
This makes it easier to run **lnav** in restricted environments without the This makes it easier to run **lnav** in restricted environments without the
risk of privilege escalation. risk of privilege escalation.
I/O Commands
------------
Anonymization
^^^^^^^^^^^^^
Anonymization is the process of removing identifying information from content
to make it safer for sharing with others. For example, an IP address can
often be used to uniquely identify an entity. Substituting all instances of
a particular IP with the same dummy value would remove the identifying data
without losing statistical accuracy. **lnav** has built-in support for
anonymization through the :code:`--anonymize` flag on the :code:`:write-*`
collection of commands. While the anonymization process should catch most
:IPv4 Addresses: Are replaced with addresses in the :code:`10.0.0.0/8` range.
:IPv6 Addresses: Are replaced with addresses in the :code:`2001:db8::/32` range.
:URL User Names: Are replaced with a random animal name.
:URL Passwords: Are replaced with a hash of the input password.
:URL Hosts: Are replaced with a random name under the example.com domain.
:URL Paths: Are recursively examined for substitution.
:URL Query Strings: Are recursively examined for substitution.
:URL Fragments: Are recursively examined for substitution.
:Paths: Are recursively examined for substitution.
:Credit Card Numbers: Are replaced with a 16 digit hash of the input number.
:MAC Addresses: Are replaced with addresses in the :code:`00:00:5E:00:53:00` range.
:Hex Dumps: Are replaced with a hash of the input replicated to the size of input.
:Email User Names: Are replaced with a random animal name.
:Email Host Names: Are replaced with a random name under the example.com domain.
:Words: Are replaced with a random word with a matching case style.
:Quoted Strings: Are recursively examined for substitution.
:UUID: Are replaced with a hash of the input.
:XML Attribute Values: Are recursively examined for substitution.
Reference Reference
--------- ---------

@ -102,7 +102,7 @@ function(bin2c)
DEPENDS bin2c "${FILE_TO_LINK}") DEPENDS bin2c "${FILE_TO_LINK}")
endfunction(bin2c) endfunction(bin2c)
foreach (FILE_TO_LINK ansi-palette.json emojis.json xml-entities.json xterm-palette.json help.txt help.md init.sql) foreach (FILE_TO_LINK animals.json ansi-palette.json diseases.json emojis.json xml-entities.json xterm-palette.json help.txt help.md init.sql words.json)
string(REPLACE "." "-" DST_FILE "${FILE_TO_LINK}") string(REPLACE "." "-" DST_FILE "${FILE_TO_LINK}")
add_custom_command( add_custom_command(
OUTPUT "${DST_FILE}.h" "${DST_FILE}.cc" OUTPUT "${DST_FILE}.h" "${DST_FILE}.cc"
@ -419,6 +419,7 @@ add_library(
sqlitepp.cc sqlitepp.cc
state-extension-functions.cc state-extension-functions.cc
styling.cc styling.cc
text_anonymizer.cc
text_format.cc text_format.cc
textfile_highlighters.cc textfile_highlighters.cc
textfile_sub_source.cc textfile_sub_source.cc
@ -535,6 +536,7 @@ add_library(
sysclip.cfg.hh sysclip.cfg.hh
term_extra.hh term_extra.hh
termios_guard.hh termios_guard.hh
text_anonymizer.hh
text_format.hh text_format.hh
textfile_highlighters.hh textfile_highlighters.hh
textfile_sub_source.hh textfile_sub_source.hh

@ -91,12 +91,15 @@ if HAVE_RE2C
endif endif
LNAV_BUILT_FILES = \ LNAV_BUILT_FILES = \
animals-json.cc \
ansi-palette-json.cc \ ansi-palette-json.cc \
builtin-scripts.cc \ builtin-scripts.cc \
builtin-sh-scripts.cc \ builtin-sh-scripts.cc \
default-config.cc \ default-config.cc \
default-formats.cc \ default-formats.cc \
diseases-json.cc \
emojis-json.cc \ emojis-json.cc \
words-json.cc \
help-md.cc \ help-md.cc \
init-sql.cc \ init-sql.cc \
time_fmts.cc \ time_fmts.cc \
@ -158,12 +161,15 @@ LDADD = \
dist_noinst_DATA = \ dist_noinst_DATA = \
alpha-release.sh \ alpha-release.sh \
animals.json \
ansi-palette.json \ ansi-palette.json \
diseases.json \
emojis.json \ emojis.json \
$(BUILTIN_LNAVSCRIPTS) \ $(BUILTIN_LNAVSCRIPTS) \
$(BUILTIN_SHSCRIPTS) \ $(BUILTIN_SHSCRIPTS) \
$(CONFIG_FILES) \ $(CONFIG_FILES) \
$(FORMAT_FILES) \ $(FORMAT_FILES) \
words.json \
xml-entities.json \ xml-entities.json \
xterm-palette.json xterm-palette.json
@ -295,6 +301,7 @@ noinst_HEADERS = \
sysclip.cfg.hh \ sysclip.cfg.hh \
termios_guard.hh \ termios_guard.hh \
term_extra.hh \ term_extra.hh \
text_anonymizer.hh \
text_format.hh \ text_format.hh \
textfile_highlighters.hh \ textfile_highlighters.hh \
textfile_sub_source.hh \ textfile_sub_source.hh \
@ -444,6 +451,7 @@ libdiag_a_SOURCES = \
statusview_curses.cc \ statusview_curses.cc \
string-extension-functions.cc \ string-extension-functions.cc \
styling.cc \ styling.cc \
text_anonymizer.cc \
text_format.cc \ text_format.cc \
textfile_sub_source.cc \ textfile_sub_source.cc \
timer.cc \ timer.cc \
@ -502,12 +510,15 @@ CLEANFILES = \
DISTCLEANFILES = \ DISTCLEANFILES = \
$(LNAV_BUILT_FILES) \ $(LNAV_BUILT_FILES) \
animals-json.h \
ansi-palette-json.h \ ansi-palette-json.h \
builtin-scripts.h \ builtin-scripts.h \
builtin-sh-scripts.h \ builtin-sh-scripts.h \
default-config.h \ default-config.h \
default-formats.h \ default-formats.h \
diseases-json.h \
emojis-json.h \ emojis-json.h \
words-json.h \
help-md.h \ help-md.h \
init-sql.h \ init-sql.h \
time_fmts.h \ time_fmts.h \

@ -0,0 +1 @@
{"data":["meerkat","aardvark","addax","alligator","alpaca","anteater","antelope","aoudad","ape","argali","armadillo","baboon","badger","basilisk","bat","bear","beaver","bighorn","bison","boar","budgerigar","buffalo","bull","bunny","burro","camel","canary","capybara","cat","chameleon","chamois","cheetah","chimpanzee","chinchilla","chipmunk","civet","coati","colt","cougar","cow","coyote","crocodile","crow","deer","dingo","doe","dung-beetle","dog","donkey","dormouse","dromedary","duckbill-platypus","dugong","eland","elephant","elk","ermine","ewe","fawn","ferret","finch","fish","fox","frog","gazelle","gemsbok","gila-monster","giraffe","gnu","goat","gopher","gorilla","grizzly-bear","ground-hog","guanaco","guinea-pig","hamster","hare","hartebeest","hedgehog","highland-cow","hippopotamus","hog","horse","hyena","ibex","iguana","impala","jackal","jaguar","jerboa","kangaroo","kitten","koala","lamb","lemur","leopard","lion","lizard","llama","lovebird","lynx","mandrill","mare","marmoset","marten","mink","mole","mongoose","monkey","moose","mountain-goat","mouse","mule","musk-deer","musk-ox","muskrat","mustang","mynah-bird","newt","ocelot","okapi","opossum","orangutan","oryx","otter","ox","panda","panther","parakeet","parrot","peccary","pig","octopus","thorny-devil","starfish","blue-crab","snowy-owl","chicken","rooster","bumble-bee","eagle-owl","polar-bear","pony","porcupine","porpoise","prairie-dog","pronghorn","puma","puppy","quagga","rabbit","raccoon","ram","rat","reindeer","rhinoceros","salamander","seal","sheep","shrew","silver-fox","skunk","sloth","snake","springbok","squirrel","stallion","steer","tapir","tiger","toad","turtle","vicuna","walrus","warthog","waterbuck","weasel","whale","wildcat","bald-eagle","wolf","wolverine","wombat","woodchuck","yak","zebra","zebu"]}

@ -36,6 +36,7 @@
#include <string.h> #include <string.h>
#include "config.h" #include "config.h"
#include "pcrepp/pcre2pp.hh"
#include "xxHash/xxhash.h" #include "xxHash/xxhash.h"
const static int TABLE_SIZE = 4095; const static int TABLE_SIZE = 4095;
@ -244,3 +245,59 @@ string_fragment::utf8_length() const
return Ok(retval); return Ok(retval);
} }
string_fragment::case_style
string_fragment::detect_text_case_style() const
{
static const auto LOWER_RE
= lnav::pcre2pp::code::from_const(R"(^[^A-Z]+$)");
static const auto UPPER_RE
= lnav::pcre2pp::code::from_const(R"(^[^a-z]+$)");
static const auto CAMEL_RE
= lnav::pcre2pp::code::from_const(R"(^(?:[A-Z][a-z0-9]+)+$)");
if (LOWER_RE.find_in(*this).ignore_error().has_value()) {
return case_style::lower;
}
if (UPPER_RE.find_in(*this).ignore_error().has_value()) {
return case_style::upper;
}
if (CAMEL_RE.find_in(*this).ignore_error().has_value()) {
return case_style::camel;
}
return case_style::mixed;
}
std::string
string_fragment::to_string_with_case_style(case_style style) const
{
std::string retval;
switch (style) {
case case_style::lower: {
for (auto ch : *this) {
retval.append(1, std::tolower(ch));
}
break;
}
case case_style::upper: {
for (auto ch : *this) {
retval.append(1, std::toupper(ch));
}
break;
}
case case_style::camel: {
retval = this->to_string();
if (!this->empty()) {
retval[0] = toupper(retval[0]);
}
break;
}
case case_style::mixed: {
return this->to_string();
}
}
return retval;
}

@ -523,6 +523,17 @@ struct string_fragment {
return scn::string_view{this->begin(), this->end()}; return scn::string_view{this->begin(), this->end()};
} }
enum class case_style {
lower,
upper,
camel,
mixed,
};
case_style detect_text_case_style() const;
std::string to_string_with_case_style(case_style style) const;
const char* sf_string; const char* sf_string;
int sf_begin; int sf_begin;
int sf_end; int sf_end;

@ -38,13 +38,25 @@
#include "base/lnav_log.hh" #include "base/lnav_log.hh"
#include "fmt/format.h" #include "fmt/format.h"
#include "optional.hpp"
template<size_t COUNT, typename T = unsigned char> template<size_t COUNT, typename T = unsigned char>
struct byte_array { struct byte_array {
static constexpr size_t BYTE_COUNT = COUNT * sizeof(T); static constexpr size_t BYTE_COUNT = COUNT * sizeof(T);
static constexpr size_t STRING_SIZE = BYTE_COUNT * 2 + 1; static constexpr size_t STRING_SIZE = BYTE_COUNT * 2 + 1;
byte_array() {} byte_array() = default;
static byte_array from(std::initializer_list<T> bytes)
{
byte_array retval;
size_t index = 0;
for (const auto by : bytes) {
retval.ba_data[index++] = by;
}
return retval;
}
byte_array(const byte_array& other) byte_array(const byte_array& other)
{ {
@ -69,19 +81,47 @@ struct byte_array {
void clear() { memset(this->ba_data, 0, BYTE_COUNT); } void clear() { memset(this->ba_data, 0, BYTE_COUNT); }
template<typename OutputIt> template<typename OutputIt>
void to_string(OutputIt out) const void to_string(OutputIt out,
nonstd::optional<char> separator = nonstd::nullopt) const
{ {
for (size_t lpc = 0; lpc < BYTE_COUNT; lpc++) { for (size_t lpc = 0; lpc < BYTE_COUNT; lpc++) {
if (lpc > 0 && separator) {
*out = separator.value();
}
fmt::format_to(out, FMT_STRING("{:02x}"), this->ba_data[lpc]); fmt::format_to(out, FMT_STRING("{:02x}"), this->ba_data[lpc]);
} }
} }
std::string to_string() const std::string to_uuid_string() const
{
return fmt::format(
FMT_STRING("{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-"
"{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}"),
this->ba_data[0 % BYTE_COUNT],
this->ba_data[1 % BYTE_COUNT],
this->ba_data[2 % BYTE_COUNT],
this->ba_data[3 % BYTE_COUNT],
this->ba_data[4 % BYTE_COUNT],
this->ba_data[5 % BYTE_COUNT],
this->ba_data[6 % BYTE_COUNT],
this->ba_data[7 % BYTE_COUNT],
this->ba_data[8 % BYTE_COUNT],
this->ba_data[9 % BYTE_COUNT],
this->ba_data[10 % BYTE_COUNT],
this->ba_data[11 % BYTE_COUNT],
this->ba_data[12 % BYTE_COUNT],
this->ba_data[13 % BYTE_COUNT],
this->ba_data[14 % BYTE_COUNT],
this->ba_data[15 % BYTE_COUNT]);
}
std::string to_string(nonstd::optional<char> separator
= nonstd::nullopt) const
{ {
std::string retval; std::string retval;
retval.reserve(STRING_SIZE); retval.reserve(STRING_SIZE);
this->to_string(std::back_inserter(retval)); this->to_string(std::back_inserter(retval), separator);
return retval; return retval;
} }
@ -94,7 +134,7 @@ struct byte_array {
return &ptr[offset]; return &ptr[offset];
} }
unsigned char ba_data[BYTE_COUNT]; unsigned char ba_data[BYTE_COUNT]{};
}; };
template<size_t COUNT, typename T = unsigned char> template<size_t COUNT, typename T = unsigned char>

@ -60,6 +60,9 @@ static struct {
{ {
"time", "time",
}, },
{
"dt",
},
/* { "qual", pcrepp("\\A([^\\s:=]+:[^\\s:=,]+(?!,)(?::[^\\s:=,]+)*)"), }, */ /* { "qual", pcrepp("\\A([^\\s:=]+:[^\\s:=,]+(?!,)(?::[^\\s:=,]+)*)"), }, */
{ {
"ipv6", "ipv6",
@ -110,31 +113,31 @@ static struct {
}, },
{ {
"lcurly", "lcur",
}, },
{ {
"rcurly", "rcur",
}, },
{ {
"lsquare", "lsqu",
}, },
{ {
"rsquare", "rsqu",
}, },
{ {
"lparen", "lpar",
}, },
{ {
"rparen", "rpar",
}, },
{ {
"langle", "lang",
}, },
{ {
"rangle", "rang",
}, },
{ {
@ -145,6 +148,9 @@ static struct {
"uuid", "uuid",
}, },
{
"cc",
},
{ {
"vers", "vers",
}, },
@ -203,7 +209,6 @@ const char* DNT_NAMES[DNT_MAX - DNT_KEY] = {
"meas", "meas",
"var", "var",
"rang", "rang",
"dt",
"grp", "grp",
}; };
@ -221,3 +226,38 @@ data_scanner::token2name(data_token_t token)
} }
return DNT_NAMES[token - DNT_KEY]; return DNT_NAMES[token - DNT_KEY];
} }
bool
data_scanner::is_credit_card(string_fragment cc) const
{
auto cc_no_spaces = cc.to_string();
auto new_end = std::remove_if(cc_no_spaces.begin(),
cc_no_spaces.end(),
[](auto ch) { return ch == ' '; });
cc_no_spaces.erase(new_end, cc_no_spaces.end());
int len = cc_no_spaces.size();
int double_even_sum = 0;
// Step 1: double every second digit, starting from right.
// if results in 2 digit number, add the digits to obtain single digit
// number. sum all answers to obtain 'double_even_sum'
for (int lpc = len - 2; lpc >= 0; lpc = lpc - 2) {
int dbl = ((cc_no_spaces[lpc] - '0') * 2);
if (dbl > 9) {
dbl = (dbl / 10) + (dbl % 10);
}
double_even_sum += dbl;
}
// Step 2: add every odd placed digit from right to double_even_sum's value
for (int lpc = len - 1; lpc >= 0; lpc = lpc - 2) {
double_even_sum += (cc_no_spaces[lpc] - 48);
}
// Step 3: check if final 'double_even_sum' is multiple of 10
// if yes, it is valid.
return double_even_sum % 10 == 0;
}

@ -44,6 +44,7 @@ enum data_token_t {
DT_MAC_ADDRESS, DT_MAC_ADDRESS,
DT_DATE, DT_DATE,
DT_TIME, DT_TIME,
DT_DATE_TIME,
DT_IPV6_ADDRESS, DT_IPV6_ADDRESS,
DT_HEX_DUMP, DT_HEX_DUMP,
DT_XML_DECL_TAG, DT_XML_DECL_TAG,
@ -79,6 +80,7 @@ enum data_token_t {
DT_IPV4_ADDRESS, DT_IPV4_ADDRESS,
DT_UUID, DT_UUID,
DT_CREDIT_CARD_NUMBER,
DT_VERSION_NUMBER, DT_VERSION_NUMBER,
DT_OCTAL_NUMBER, DT_OCTAL_NUMBER,
DT_PERCENTAGE, DT_PERCENTAGE,
@ -107,7 +109,6 @@ enum data_token_t {
DNT_MEASUREMENT, DNT_MEASUREMENT,
DNT_VARIABLE_KEY, DNT_VARIABLE_KEY,
DNT_ROWRANGE, DNT_ROWRANGE,
DNT_DATE_TIME,
DNT_GROUP, DNT_GROUP,
DNT_MAX, DNT_MAX,
@ -198,6 +199,8 @@ public:
} }
private: private:
bool is_credit_card(string_fragment frag) const;
std::string ds_line; std::string ds_line;
shared_buffer_ref ds_sbr; shared_buffer_ref ds_sbr;
string_fragment ds_input; string_fragment ds_input;

File diff suppressed because it is too large Load Diff

@ -31,6 +31,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/socket.h> #include <sys/socket.h>
#include "base/date_time_scanner.hh"
#include "config.h" #include "config.h"
#include "data_scanner.hh" #include "data_scanner.hh"
@ -56,6 +57,38 @@ nonstd::optional<data_scanner::tokenize_result> data_scanner::tokenize2()
return tokenize_result{token_out, cap_all, cap_inner, this->ds_input.data()}; \ return tokenize_result{token_out, cap_all, cap_inner, this->ds_input.data()}; \
} }
static const unsigned char *EMPTY = (const unsigned char *) ""; static const unsigned char *EMPTY = (const unsigned char *) "";
if (this->ds_next_offset < this->ds_input.length()) {
date_time_scanner dts;
struct exttm tm;
struct timeval tv;
auto dt_end = dts.scan(this->ds_input.data() + this->ds_next_offset,
this->ds_input.length() - this->ds_next_offset,
nullptr,
&tm,
tv);
if (dt_end != nullptr &&
!(tm.et_flags & ETF_MACHINE_ORIENTED) &&
(tm.et_flags & ETF_DAY_SET ||
(tm.et_flags & ETF_HOUR_SET && tm.et_flags & ETF_MINUTE_SET))) {
cap_all.c_begin = this->ds_next_offset;
cap_inner.c_begin = this->ds_next_offset;
this->ds_next_offset = dt_end - this->ds_input.data();
cap_all.c_end = this->ds_next_offset;
cap_inner.c_end = this->ds_next_offset;
if (tm.et_flags & ETF_DAY_SET) {
if (tm.et_flags & ETF_MINUTE_SET) {
token_out = DT_DATE_TIME;
} else {
token_out = DT_DATE;
}
} else {
token_out = DT_TIME;
}
return tokenize_result{token_out, cap_all, cap_inner, this->ds_input.data()};
}
}
struct _YYCURSOR { struct _YYCURSOR {
YYCTYPE operator*() const { YYCTYPE operator*() const {
if (this->val < this->lim) { if (this->val < this->lim) {
@ -169,8 +202,8 @@ nonstd::optional<data_scanner::tokenize_result> data_scanner::tokenize2()
("/"|"./"|"../"|[A-Z]":\\"|"\\\\")("Program Files"(" (x86)")?)?[a-zA-Z0-9_\.\-\~/\\!@#$%^&*()]* { RET(DT_PATH); } ("/"|"./"|"../"|[A-Z]":\\"|"\\\\")("Program Files"(" (x86)")?)?[a-zA-Z0-9_\.\-\~/\\!@#$%^&*()]* { RET(DT_PATH); }
(SPACE|NUM)NUM":"NUM{2}/[^:] { RET(DT_TIME); } (SPACE|NUM)NUM":"NUM{2}/[^:] { RET(DT_TIME); }
(SPACE|NUM)NUM?":"NUM{2}":"NUM{2}("."NUM{3,6})?/[^:] { RET(DT_TIME); } (SPACE|NUM)NUM?":"NUM{2}":"NUM{2}("."NUM{3,6})?/[^:] { RET(DT_TIME); }
[0-9a-fA-F][0-9a-fA-F](":"[0-9a-fA-F][0-9a-fA-F])+ { [0-9a-fA-F][0-9a-fA-F]((":"|"-")[0-9a-fA-F][0-9a-fA-F])+ {
if ((YYCURSOR - this->ds_input.udata()) == 17) { if ((YYCURSOR.val - (this->ds_input.udata() + this->ds_next_offset)) == 17) {
RET(DT_MAC_ADDRESS); RET(DT_MAC_ADDRESS);
} else { } else {
RET(DT_HEX_DUMP); RET(DT_HEX_DUMP);
@ -225,6 +258,19 @@ nonstd::optional<data_scanner::tokenize_result> data_scanner::tokenize2()
[0-9a-fA-F]{8}("-"[0-9a-fA-F]{4}){3}"-"[0-9a-fA-F]{12} { RET(DT_UUID); } [0-9a-fA-F]{8}("-"[0-9a-fA-F]{4}){3}"-"[0-9a-fA-F]{12} { RET(DT_UUID); }
(NUM{4}" "NUM{4}" "NUM{4}" "NUM{4}|NUM{16})/[^0-9] {
CAPTURE(DT_CREDIT_CARD_NUMBER);
if (!this->is_credit_card(this->to_string_fragment(cap_all))) {
if (cap_all.length() > 16) {
cap_all.c_end = cap_all.c_begin + 4;
cap_inner.c_end = cap_inner.c_begin + 4;
}
this->ds_next_offset = cap_all.c_end;
token_out = DT_NUMBER;
}
return tokenize_result{token_out, cap_all, cap_inner, this->ds_input.data()};
}
[0-9]"."[0-9]+'e'[\-\+][0-9]+ { RET(DT_NUMBER); } [0-9]"."[0-9]+'e'[\-\+][0-9]+ { RET(DT_NUMBER); }
[0-9]+("."[0-9]+[a-zA-Z0-9_]*){2,}("-"[a-zA-Z0-9_]+)?|[0-9]+("."[0-9]+[a-zA-Z0-9_]*)+"-"[a-zA-Z0-9_]+ { [0-9]+("."[0-9]+[a-zA-Z0-9_]*){2,}("-"[a-zA-Z0-9_]+)?|[0-9]+("."[0-9]+[a-zA-Z0-9_]*)+"-"[a-zA-Z0-9_]+ {

@ -0,0 +1,549 @@
{
"data": [
"achondroplasia",
"acinetobacter-infections",
"acne",
"actinomycosis",
"addisons-disease",
"african-sleeping-sickness",
"agammaglobulinemia",
"albinism",
"alcoholic-hepatitis",
"allergy",
"alopecia",
"alopecia-areata",
"alzheimers-disease",
"amblyopia",
"amebiasis",
"ampylobacter-infection",
"amyloidosis",
"anaplasmosis",
"anemia",
"aneurdu",
"ankylosing-spondylitis",
"anorexia",
"anosmia",
"anotia",
"anthrax",
"anti-gbm",
"anti-tbm-nephritis",
"antiphospholipid-syndrome",
"appendicitis",
"apraxia",
"arcanobacterium-haemolyticum-infection",
"argentine-hemorrhagic-fever",
"argyria",
"arthritis",
"ascariasis",
"aseptic-meningitis",
"aspergillosis",
"asthenia",
"asthma",
"astigmatism",
"astrovirus-infection",
"atherosclerosis",
"athetosis",
"atrophy",
"autoimmune-angioedema",
"autoimmune-aplastic-anemia",
"autoimmune-dysautonomia",
"autoimmune-hepatitis",
"autoimmune-hyperlipidemia",
"autoimmune-immunodeficiency",
"autoimmune-inner-ear-disease",
"autoimmune-myocarditis",
"autoimmune-oophoritis",
"autoimmune-pancreatitis",
"autoimmune-retinopathy",
"autoimmune-thrombocytopenic-purpura",
"autoimmune-thyroid-disease",
"autoimmune-urticaria",
"axonal-&-neuronal-neuropathies",
"babesiosis",
"bacillary-dysentery",
"bacillus-cereus-infection",
"bacterial-meningitis",
"bacterial-pneumonia",
"bacterial-vaginosis",
"bacteroides-infection",
"balantidiasis",
"balo-disease",
"barbers-itch",
"baylisascaris-infection",
"behcets-disease",
"beriberi",
"bk-virus-infection",
"black-death",
"black-piedra",
"blastocystis-hominis-infection",
"blastomycosis",
"bolivian-hemorrhagic-fever",
"borrelia-infection",
"botulism",
"brazilian-hemorrhagic-fever",
"breast-cancer",
"bronchitis",
"brucellosis",
"bubonic-plague",
"bullous-pemphigoid",
"bunion",
"burkholderia-infection",
"buruli-ulcer",
"calculi",
"calicivirus-infection",
"campylobacteriosis",
"cancer",
"candidiasis",
"carbon-monoxide-poisoning",
"cardiomyopathy",
"castleman-disease",
"cat-scratch-disease",
"celiac-disease",
"celiacs-disease",
"cellulitis",
"cerebral-palsy",
"chagas-disease",
"chalazion",
"chancroid",
"chavia",
"cherubism",
"chickenpox",
"chikungunya",
"chlamydia",
"chlamydia-trachomatis",
"chlamydophila-pneumoniae-infection",
"cholera",
"chordoma",
"chorea",
"chromoblastomycosis",
"chronic-fatigue-syndrome",
"chronic-inflammatory-demyelinating-polyneuropathy",
"chronic-recurrent-multifocal-ostomyelitis",
"churg-strauss-syndrome",
"circadian-rhythm-sleep-disorder",
"clonorchiasis",
"clostridial-myonecrosis",
"clostridium-difficile-infection",
"coccidioidomycosis",
"cogans-syndrome",
"cold-agglutinin-disease",
"colitis",
"colorado-tick-fever",
"common-cold",
"condyloma",
"congenital-heart-block",
"congestive-heart-disease",
"coronary-heart-disease",
"cowpox",
"coxsackie-myocarditis",
"crest-disease",
"cretinism",
"creutzfeldt-jakob-disease",
"crimean-congo-hemorrhagic-fever",
"crohns-disease",
"cryptococcosis",
"cryptosporidiosis",
"cutaneous-larva-migrans",
"cyclosporiasis",
"cysticercosis",
"cytomegalovirus-infection",
"demyelinating-neuropathies",
"dengue-fever",
"dermatitis-herpetiformis",
"dermatomyositis",
"devics-disease",
"diabetes-mellitus",
"dientamoebiasis",
"diphtheria",
"diphyllobothriasis",
"discoid-lupus",
"donovanosis",
"dracunculiasis",
"dresslers-syndrome",
"ear-infection",
"ebola",
"ebola-hemorrhagic-fever",
"echinococcosis",
"ehrlichiosis",
"elephantiasis",
"emphysema",
"encephalitis",
"endometriosis",
"enterovirus-infection",
"eosinophilic-esophagitis",
"eosinophilic-fasciitis",
"epidemic-typhus",
"epilepsy",
"erectile-dysfunctions",
"erythema-infectiosum",
"erythema-nodosum",
"essential-mixed-cryoglobulinemia",
"evans-syndrome",
"exanthem-subitum",
"experimental-allergic-encephalomyelitis",
"fasciolopsiasis",
"fasciolosis",
"fatal-familial-insomnia",
"fibromyalgia",
"fibrosing-alveolitis",
"fifth-disease",
"filariasis",
"foodborne-illness",
"free-living-amebic-infection",
"fusobacterium-infection",
"gangrene",
"gas-gangrene",
"gastroenteritis",
"genital-herpes",
"geotrichosis",
"gerd",
"gerstmann-sträussler-scheinker-syndrome",
"giant-cell-arteritis",
"giant-cell-myocarditis",
"giardiasis",
"glanders",
"glomerulonephritis",
"gnathostomiasis",
"goitre",
"gonorrhea",
"goodpastures-syndrome",
"granuloma-inguinale",
"graves-disease",
"group-a-streptococcal-infection",
"group-b-streptococcal-infection",
"guillain-barre-syndrome",
"haemophilus-influenzae-infection",
"hand-foot-and-mouth-disease",
"hantavirus-pulmonary-syndrome",
"hashimotos-encephalitis",
"hashimotos-thyroiditis",
"heart-disease",
"heartland-virus-disease",
"helicobacter-pylori-infection",
"hemolytic-anemia",
"hemolytic-uremic-syndrome",
"henoch-schonlein-purpura",
"hepatitis-a",
"hepatitis-b",
"hepatitis-c",
"hepatitis-d",
"hepatitis-e",
"herpes-gestationis",
"herpes-simplex",
"histoplasmosis",
"hiv",
"hookworm-infection",
"human-bocavirus-infection",
"human-ewingii-ehrlichiosis",
"human-granulocytic-anaplasmosis",
"human-metapneumovirus-infection",
"human-monocytic-ehrlichiosis",
"human-papillomavirus-(hpv)",
"human-parainfluenza-virus-infection",
"huntingtons-disease",
"hymenolepiasis",
"hypermetropia",
"hyperopia",
"hyperthyroidism",
"hypogammaglobulinemia",
"hypothyroid",
"hypotonia",
"idiopathic-pulmonary-fibrosis",
"idiopathic-thrombocytopenic-purpura",
"iga-nephropathy",
"igg4-related-sclerosing-disease",
"ignious-syndrome",
"immunoregulatory-lipoproteins",
"impetigo",
"inclusion-body-myositis",
"infertility",
"influenza",
"interstitial-cystitis",
"iritis",
"iron-deficiency-anemia",
"irritable-bowel-syndrome",
"isosporiasis",
"jaundice",
"juvenile-arthritis",
"juvenile-diabetes",
"juvenile-myositis",
"kawasaki-disease",
"kawasaki-syndrome",
"keloids",
"keratitis",
"kingella-kingae-infection",
"kuru",
"kwashiorkor",
"lambert-eaton-syndrome",
"laryngitis",
"lassa-fever",
"lead-poisoning",
"legionellosis",
"legionnaires-disease",
"leishmaniasis",
"leprosy",
"leptospirosis",
"leukemia",
"leukocytoclastic-vasculitis",
"lice",
"lichen-planus",
"lichen-sclerosus",
"ligneous-conjunctivitis",
"listeriosis",
"lockjaw",
"loiasis",
"lung-cancer",
"lupus",
"lupus-erythematosus",
"lyme-disease",
"lymphocytic-choriomeningitis",
"lymphogranuloma-venereum",
"lymphoma",
"mad-cow-disease",
"malaria",
"marburg-fever",
"marburg-hemorrhagic-fever",
"mattticular-syndrome",
"measles",
"melanoma",
"melioidosis",
"menieres-disease",
"meningitis",
"meningococcal-disease",
"metagonimiasis",
"metastatic-cancer",
"microscopic-polyangiitis",
"microsporidiosis",
"middle-east-respiratory-syndrome",
"migraine",
"mixed-connective-tissue-disease",
"molluscum-contagiosum",
"monkeypox",
"mononucleosis",
"moorens-ulcer",
"morquio-syndrome",
"mucha-habermann-disease",
"multiple-myeloma",
"multiple-sclerosis",
"mumps",
"murine-typhus",
"muscular-dystrophy",
"myasthenia-gravis",
"mycetoma",
"mycoplasma-pneumonia",
"myelitis",
"myiasis",
"myoclonus",
"myopia",
"myositis",
"myxedema",
"ménières-disease",
"narcolepsy",
"necrotizing-fasciitis",
"neonatal-conjunctivitis",
"neoplasm",
"neuromyelitis-optica",
"neutropenia",
"night-blindness",
"nocardiosis",
"non-gonococcal-urethritis",
"obesity",
"ocular-cicatricial-pemphigoid",
"onchocerciasis",
"optic-neuritis",
"osteoarthritis",
"osteoporosis",
"otitis",
"palindromic-rheumatism",
"paracoccidioidomycosis",
"paragonimiasis",
"paraneoplastic-cerebellar-degeneration",
"paratyphoid-fever",
"parkinsons-disease",
"paroxysmal-nocturnal-hemoglobinuria",
"parry-romberg-syndrome",
"pars-planitis",
"parsonnage-turner-syndrome",
"pasteurellosis",
"pediculosis-capitis-(head-lice)",
"pediculosis-corporis-(body-lice)",
"pediculosis-pubis-(pubic-lice)",
"pelvic-inflammatory-disease",
"pemphigus",
"periodontal-disease",
"peripheral-neuropathy",
"peritonitis",
"perivenous-encephalomyelitis",
"pernicious-anemia",
"pertussis",
"phenylketonuria",
"pilia",
"pinworm-infection",
"plague",
"pneumococcal-infection",
"pneumocystis-pneumonia",
"pneumonia",
"pneumonia",
"poems-syndrome",
"poliomyelitis",
"polyarteritis-nodosa",
"polymyalgia-rheumatica",
"polymyositis",
"pontiac-fever",
"porphyria",
"postmyocardial-infarction-syndrome",
"postpericardiotomy-syndrome",
"prevotella-infection",
"primary-amoebic-meningoencephalitis",
"primary-biliary-cirrhosis",
"primary-sclerosing-cholangitis",
"progeria",
"progesterone-dermatitis",
"progressive-multifocal-leukoencephalopathy",
"prostatitis",
"psittacosis",
"psoriasis",
"psoriatic-arthritis",
"pubic-lice",
"pulmonary-embolism",
"pure-red-cell-aplasia",
"pyoderma-gangrenosum",
"q-fever",
"ques-fever",
"rabies",
"rat-bite-fever",
"raynauds-phenomenon",
"reactive-arthritis",
"reflex-sympathetic-dystrophy",
"reiters-syndrome",
"relapsing-polychondritis",
"repetitive-strain-injury",
"respiratory-syncytial-virus-infection",
"restless-legs-syndrome",
"retroperitoneal-fibrosis",
"rheumatic-fever",
"rheumatic-heart",
"rheumatism",
"rheumatoid-arthritis",
"rhinosporidiosis",
"rhinovirus-infection",
"rickets",
"rickettsial-infection",
"rickettsialpox",
"rift-valley-fever",
"ringworm",
"river-blindness",
"rocky-mountain-spotted-fever",
"rotavirus-infection",
"rubella",
"salmonellosis",
"sarcoidosis",
"sars",
"scabies",
"scarlet-fever",
"schistosomiasis",
"schizophrenia",
"schmidt-syndrome",
"sciatica",
"scleritis",
"scleroderma",
"scrapie",
"scurvy",
"sepsis",
"septicemia",
"shigellosis",
"shin-splints",
"shingles",
"sickle-cell-anemia",
"siderosis",
"sids",
"silicosis",
"sixth-disease",
"sjogrens-syndrome",
"smallpox",
"south-american-blastomycosis",
"sperm-&-testicular-autoimmunity",
"sporotrichosis",
"staphylococcal-food-poisoning",
"staphylococcal-infection",
"stevens-johnson-syndrome",
"stiff-person-syndrome",
"stomach-flu",
"stomach-ulcers",
"strabismus",
"strep-throat",
"streptococcal-infection",
"strongyloidiasis",
"subacute-bacterial-endocarditis",
"subacute-sclerosing-panencephalitis",
"susacs-syndrome",
"swine-influenza",
"sympathetic-ophthalmia",
"synovitis",
"syphilis",
"taeniasis",
"takayasus-arteritis",
"tay-sachs-disease",
"temporal-arteritis/giant-cell-arteritis",
"tennis-elbow",
"teratoma",
"tetanus",
"thalassaemia",
"thrombocytopenic-purpura",
"thrush",
"thymoma",
"tinea-barbae",
"tinnitus",
"tolosa-hunt-syndrome",
"tonsillitis",
"tooth-decay",
"toxic-shock-syndrome",
"toxocariasis",
"transverse-myelitis",
"trichinosis",
"trichomoniasis",
"trichuriasis",
"trinochccliasis",
"trisomy",
"tuberculosis",
"tularemia",
"tumor",
"tungiasis",
"type-1-diabetes",
"typhoid-fever",
"typhus",
"ulcerative-colitis",
"ulcers",
"undifferentiated-connective-tissue-disease",
"ureaplasma-urealyticum-infection",
"uremia",
"urticaria",
"uveitis",
"valley-fever",
"varicella",
"varicose-veins",
"vasculitis",
"vasovagal-syncope",
"venezuelan-equine-encephalitis",
"venezuelan-hemorrhagic-fever",
"vesiculobullous-dermatosis",
"viral-fever",
"viral-meningitis",
"viral-pneumonia",
"vitiligo",
"von-hippel-lindau-disease",
"warkany-syndrome",
"warts",
"watkins",
"wegeners-granulomatosis",
"west-nile-fever",
"whipworm-infection",
"white-piedra",
"whitmores-disease",
"whooping-cough",
"yellow-fever",
"yersinia-pseudotuberculosis-infection",
"yersiniosis",
"zygomycosis"
]
}

@ -34,6 +34,7 @@ logfmt_parser_test_SOURCES = \
logfmt_parser_test_LDADD = \ logfmt_parser_test_LDADD = \
liblogfmt.a \ liblogfmt.a \
$(top_builddir)/src/base/libbase.a \ $(top_builddir)/src/base/libbase.a \
$(top_builddir)/src/pcrepp/libpcrepp.a \
$(top_builddir)/src/third-party/scnlib/src/libscnlib.a $(top_builddir)/src/third-party/scnlib/src/libscnlib.a
TESTS = \ TESTS = \

@ -1415,12 +1415,13 @@
.. _write_table_to: .. _write_table_to:
:write-table-to *path* :write-table-to *\[--anonymize\]* *path*
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Write SQL results to the given file in a tabular format Write SQL results to the given file in a tabular format
**Parameters** **Parameters**
* **--anonymize** --- Anonymize the table contents
* **path\*** --- The path to the file to write * **path\*** --- The path to the file to write
**Examples** **Examples**
@ -1438,12 +1439,13 @@
.. _write_csv_to: .. _write_csv_to:
:write-csv-to *path* :write-csv-to *\[--anonymize\]* *path*
^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Write SQL results to the given file in CSV format Write SQL results to the given file in CSV format
**Parameters** **Parameters**
* **--anonymize** --- Anonymize the row contents
* **path\*** --- The path to the file to write * **path\*** --- The path to the file to write
**Examples** **Examples**
@ -1461,12 +1463,13 @@
.. _write_json_to: .. _write_json_to:
:write-json-to *path* :write-json-to *\[--anonymize\]* *path*
^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Write SQL results to the given file in JSON format Write SQL results to the given file in JSON format
**Parameters** **Parameters**
* **--anonymize** --- Anonymize the JSON values
* **path\*** --- The path to the file to write * **path\*** --- The path to the file to write
**Examples** **Examples**
@ -1484,12 +1487,13 @@
.. _write_jsonlines_to: .. _write_jsonlines_to:
:write-jsonlines-to *path* :write-jsonlines-to *\[--anonymize\]* *path*
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Write SQL results to the given file in JSON Lines format Write SQL results to the given file in JSON Lines format
**Parameters** **Parameters**
* **--anonymize** --- Anonymize the JSON values
* **path\*** --- The path to the file to write * **path\*** --- The path to the file to write
**Examples** **Examples**
@ -1507,13 +1511,14 @@
.. _write_raw_to: .. _write_raw_to:
:write-raw-to *\[--view={log,db}\]* *path* :write-raw-to *\[--view={log,db}\]* *\[--anonymize\]* *path*
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In the log view, write the original log file content of the marked messages to the file. In the DB view, the contents of the cells are written to the output file. In the log view, write the original log file content of the marked messages to the file. In the DB view, the contents of the cells are written to the output file.
**Parameters** **Parameters**
* **--view={log,db}** --- The view to use as the source of data * **--view={log,db}** --- The view to use as the source of data
* **--anonymize** --- Anonymize the lines
* **path\*** --- The path to the file to write * **path\*** --- The path to the file to write
**Examples** **Examples**
@ -1531,12 +1536,13 @@
.. _write_screen_to: .. _write_screen_to:
:write-screen-to *path* :write-screen-to *\[--anonymize\]* *path*
^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Write the displayed text or SQL results to the given file without any formatting Write the displayed text or SQL results to the given file without any formatting
**Parameters** **Parameters**
* **--anonymize** --- Anonymize the lines
* **path\*** --- The path to the file to write * **path\*** --- The path to the file to write
**Examples** **Examples**
@ -1554,12 +1560,13 @@
.. _write_to: .. _write_to:
:write-to *path* :write-to *\[--anonymize\]* *path*
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Overwrite the given file with any marked lines in the current view Overwrite the given file with any marked lines in the current view
**Parameters** **Parameters**
* **--anonymize** --- Anonymize the lines
* **path\*** --- The path to the file to write * **path\*** --- The path to the file to write
**Examples** **Examples**
@ -1577,12 +1584,13 @@
.. _write_view_to: .. _write_view_to:
:write-view-to *path* :write-view-to *\[--anonymize\]* *path*
^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Write the text in the top view to the given file without any formatting Write the text in the top view to the given file without any formatting
**Parameters** **Parameters**
* **--anonymize** --- Anonymize the lines
* **path\*** --- The path to the file to write * **path\*** --- The path to the file to write
**Examples** **Examples**

@ -480,6 +480,30 @@ acosh(*num*)
---- ----
.. _anonymize:
anonymize(*value*)
^^^^^^^^^^^^^^^^^^
Replace identifying information with random values.
**Parameters**
* **value\*** --- The text to anonymize
**Examples**
To anonymize an IP address:
.. code-block:: custsqlite
;SELECT anonymize('Hello, 192.168.1.2')
Aback, 10.0.0.1
**See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
----
.. _asin: .. _asin:
asin(*num*) asin(*num*)
@ -772,7 +796,7 @@ char(*X*)
HI HI
**See Also** **See Also**
:ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -805,7 +829,7 @@ charindex(*needle*, *haystack*, *\[start\]*)
0 0
**See Also** **See Also**
:ref:`char`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -973,7 +997,7 @@ decode(*value*, *algorithm*)
curl curl
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -1117,7 +1141,7 @@ encode(*value*, *algorithm*)
Hello%2C%20World%21 Hello%2C%20World%21
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -1149,7 +1173,7 @@ endswith(*str*, *suffix*)
0 0
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -1204,7 +1228,7 @@ extract(*str*)
{"col_0":1.0,"col_1":2.0} {"col_0":1.0,"col_1":2.0}
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -1405,7 +1429,7 @@ group_concat(*X*, *\[sep\]*)
hw,gw hw,gw
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -1429,7 +1453,7 @@ group_spooky_hash(*str*)
4e7a190aead058cb123c94290f29c34a 4e7a190aead058cb123c94290f29c34a
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -1445,7 +1469,7 @@ gunzip(*b*)
* **b** --- The blob to decompress * **b** --- The blob to decompress
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -1461,7 +1485,7 @@ gzip(*value*)
* **value** --- The value to compress * **value** --- The value to compress
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -1514,7 +1538,7 @@ humanize_duration(*secs*)
1s500 1s500
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`date`, :ref:`datetime`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`julianday`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`strftime`, :ref:`substr`, :ref:`time`, :ref:`timediff`, :ref:`timeslice`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`date`, :ref:`datetime`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`julianday`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`strftime`, :ref:`substr`, :ref:`time`, :ref:`timediff`, :ref:`timeslice`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -1538,7 +1562,7 @@ humanize_file_size(*value*)
10.0MB 10.0MB
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -1586,7 +1610,7 @@ instr(*haystack*, *needle*)
2 2
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -1939,7 +1963,7 @@ leftstr(*str*, *N*)
abc abc
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -1963,7 +1987,7 @@ length(*str*)
3 3
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2153,7 +2177,7 @@ logfmt2json(*str*)
{"foo":1,"bar":2,"name":"Rolo Tomassi"} {"foo":1,"bar":2,"name":"Rolo Tomassi"}
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2177,7 +2201,7 @@ lower(*str*)
abc abc
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2209,7 +2233,7 @@ ltrim(*str*, *\[chars\]*)
c c
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2366,7 +2390,7 @@ padc(*str*, *len*)
abcdef ghi abcdef ghi
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2398,7 +2422,7 @@ padl(*str*, *len*)
abcdef abcdef
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2430,7 +2454,7 @@ padr(*str*, *len*)
abcdefghi abcdefghi
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2528,7 +2552,7 @@ printf(*format*, *X*)
value: 00011 value: 00011
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2552,7 +2576,7 @@ proper(*str*)
Hello, World! Hello, World!
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2735,7 +2759,7 @@ regexp_capture(*string*, *pattern*)
1 2 <NULL> 3 8 9 2 1 2 <NULL> 3 8 9 2
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2763,7 +2787,7 @@ regexp_capture_into_json(*string*, *pattern*, *\[options\]*)
1 {"col_0":"b","col_1":2} 1 {"col_0":"b","col_1":2}
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2802,7 +2826,7 @@ regexp_match(*re*, *str*)
{"num":123,"str":"four"} {"num":123,"str":"four"}
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_replace`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_replace`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2835,7 +2859,7 @@ regexp_replace(*str*, *re*, *repl*)
<123> <abc> <123> <abc>
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_match`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_match`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2868,7 +2892,7 @@ replace(*str*, *old*, *replacement*)
zbc zbc
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2893,7 +2917,7 @@ replicate(*str*, *N*)
abcabcabc abcabcabc
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2917,7 +2941,7 @@ reverse(*str*)
cba cba
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -2949,7 +2973,7 @@ rightstr(*str*, *N*)
abc abc
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -3045,7 +3069,7 @@ rtrim(*str*, *\[chars\]*)
a a
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -3115,7 +3139,7 @@ sparkline(*value*, *\[upper\]*)
▁▂▃▄▅▆▇█ ▁▂▃▄▅▆▇█
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -3160,7 +3184,7 @@ spooky_hash(*str*)
f96b3d9c1a19f4394c97a1b79b1880df f96b3d9c1a19f4394c97a1b79b1880df
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -3274,7 +3298,7 @@ startswith(*str*, *prefix*)
0 0
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -3299,7 +3323,7 @@ strfilter(*source*, *include*)
bcbc bcbc
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -3386,7 +3410,7 @@ substr(*str*, *start*, *\[size\]*)
b b
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -3593,7 +3617,7 @@ trim(*str*, *\[chars\]*)
abc abc
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`unicode`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
---- ----
@ -3646,7 +3670,7 @@ unicode(*X*)
97 97
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`upper`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`upper`, :ref:`xpath`
---- ----
@ -3684,7 +3708,7 @@ upper(*str*)
ABC ABC
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`xpath` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`xpath`
---- ----
@ -3727,7 +3751,7 @@ xpath(*xpath*, *xmldoc*)
Hello ★ /abc/def/text() {} Hello ★ Hello ★ /abc/def/text() {} Hello ★
**See Also** **See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper` :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`
---- ----

@ -79,6 +79,7 @@
#include "sqlite-extension-func.hh" #include "sqlite-extension-func.hh"
#include "sysclip.hh" #include "sysclip.hh"
#include "tailer/tailer.looper.hh" #include "tailer/tailer.looper.hh"
#include "text_anonymizer.hh"
#include "url_loader.hh" #include "url_loader.hh"
#include "yajl/api/yajl_parse.h" #include "yajl/api/yajl_parse.h"
#include "yajlpp/json_op.hh" #include "yajlpp/json_op.hh"
@ -871,9 +872,9 @@ yajl_writer(void* context, const char* str, size_t len)
} }
static void static void
json_write_row(yajl_gen handle, int row) json_write_row(yajl_gen handle, int row, lnav::text_anonymizer& ta, bool anonymize)
{ {
db_label_source& dls = lnav_data.ld_db_row_source; auto& dls = lnav_data.ld_db_row_source;
yajlpp_map obj_map(handle); yajlpp_map obj_map(handle);
for (size_t col = 0; col < dls.dls_headers.size(); col++) { for (size_t col = 0; col < dls.dls_headers.size(); col++) {
@ -884,7 +885,7 @@ json_write_row(yajl_gen handle, int row)
continue; continue;
} }
db_label_source::header_meta& hm = dls.dls_headers[col]; auto& hm = dls.dls_headers[col];
switch (hm.hm_column_type) { switch (hm.hm_column_type) {
case SQLITE_FLOAT: case SQLITE_FLOAT:
@ -952,12 +953,12 @@ json_write_row(yajl_gen handle, int row)
break; break;
} }
default: default:
obj_map.gen(dls.dls_rows[row][col]); obj_map.gen(anonymize ? ta.next(string_fragment::from_c_str(dls.dls_rows[row][col])) : dls.dls_rows[row][col]);
break; break;
} }
break; break;
default: default:
obj_map.gen(dls.dls_rows[row][col]); obj_map.gen(anonymize ? ta.next(string_fragment::from_c_str(dls.dls_rows[row][col])) : dls.dls_rows[row][col]);
break; break;
} }
} }
@ -972,6 +973,7 @@ com_save_to(exec_context& ec,
const char* mode = ""; const char* mode = "";
std::string fn, retval; std::string fn, retval;
bool to_term = false; bool to_term = false;
bool anonymize = false;
int (*closer)(FILE*) = fclose; int (*closer)(FILE*) = fclose;
if (args.empty()) { if (args.empty()) {
@ -988,6 +990,12 @@ com_save_to(exec_context& ec,
return ec.make_error("unable to parse arguments"); return ec.make_error("unable to parse arguments");
} }
auto anon_iter = std::find(split_args.begin(), split_args.end(), "--anonymize");
if (anon_iter != split_args.end()) {
split_args.erase(anon_iter);
anonymize = true;
}
auto* tc = *lnav_data.ld_view_stack.top(); auto* tc = *lnav_data.ld_view_stack.top();
auto opt_view_name = find_arg(split_args, "--view"); auto opt_view_name = find_arg(split_args, "--view");
if (opt_view_name) { if (opt_view_name) {
@ -1017,6 +1025,7 @@ com_save_to(exec_context& ec,
auto& dls = lnav_data.ld_db_row_source; auto& dls = lnav_data.ld_db_row_source;
bookmark_vector<vis_line_t> all_user_marks; bookmark_vector<vis_line_t> all_user_marks;
lnav::text_anonymizer ta;
if (args[0] == "write-csv-to" || args[0] == "write-json-to" if (args[0] == "write-csv-to" || args[0] == "write-json-to"
|| args[0] == "write-jsonlines-to" || args[0] == "write-cols-to" || args[0] == "write-jsonlines-to" || args[0] == "write-cols-to"
@ -1111,7 +1120,7 @@ com_save_to(exec_context& ec,
if (!first) { if (!first) {
fprintf(outfile, ","); fprintf(outfile, ",");
} }
csv_write_string(outfile, *iter); csv_write_string(outfile, anonymize ? ta.next(string_fragment::from_c_str(*iter)) : *iter);
first = false; first = false;
} }
fprintf(outfile, "\n"); fprintf(outfile, "\n");
@ -1164,16 +1173,18 @@ com_save_to(exec_context& ec,
fprintf(outfile, "\u2502"); fprintf(outfile, "\u2502");
auto cell = dls.dls_rows[row][col]; auto cell = std::string(dls.dls_rows[row][col]);
auto cell_byte_len = strlen(cell); if (anonymize) {
auto cell_length = utf8_string_length(cell, cell_byte_len) cell = ta.next(cell);
.unwrapOr(cell_byte_len); }
auto padding = hdr.hm_column_size - cell_length; auto cell_length = utf8_string_length(cell)
.unwrapOr(cell.size());
auto padding = anonymize ? 1 : hdr.hm_column_size - cell_length;
if (hdr.hm_column_type != SQLITE3_TEXT) { if (hdr.hm_column_type != SQLITE3_TEXT) {
fprintf(outfile, "%s", std::string(padding, ' ').c_str()); fprintf(outfile, "%s", std::string(padding, ' ').c_str());
} }
fprintf(outfile, "%s", cell); fprintf(outfile, "%s", cell.c_str());
if (hdr.hm_column_type == SQLITE3_TEXT) { if (hdr.hm_column_type == SQLITE3_TEXT) {
fprintf(outfile, "%s", std::string(padding, ' ').c_str()); fprintf(outfile, "%s", std::string(padding, ' ').c_str());
} }
@ -1210,7 +1221,7 @@ com_save_to(exec_context& ec,
break; break;
} }
json_write_row(gen, row); json_write_row(gen, row, ta, anonymize);
line_count += 1; line_count += 1;
} }
} }
@ -1225,7 +1236,7 @@ com_save_to(exec_context& ec,
break; break;
} }
json_write_row(gen, row); json_write_row(gen, row, ta, anonymize);
yajl_gen_reset(gen, "\n"); yajl_gen_reset(gen, "\n");
line_count += 1; line_count += 1;
} }
@ -1249,7 +1260,7 @@ com_save_to(exec_context& ec,
auto* los = tc->get_overlay_source(); auto* los = tc->get_overlay_source();
tc->listview_value_for_rows(*tc, top, rows); tc->listview_value_for_rows(*tc, top, rows);
for (const auto& al : rows) { for (auto& al : rows) {
while (los != nullptr while (los != nullptr
&& los->list_value_for_overlay( && los->list_value_for_overlay(
*tc, y, tc->get_inner_height(), top, ov_al)) *tc, y, tc->get_inner_height(), top, ov_al))
@ -1258,6 +1269,10 @@ com_save_to(exec_context& ec,
++y; ++y;
} }
wrapped_count += vis_line_t((al.length() - 1) / (dim.second - 2)); wrapped_count += vis_line_t((al.length() - 1) / (dim.second - 2));
if (anonymize) {
al.al_attrs.clear();
al.al_string = ta.next(al.al_string);
}
write_line_to(outfile, al); write_line_to(outfile, al);
line_count += 1; line_count += 1;
@ -1295,7 +1310,11 @@ com_save_to(exec_context& ec,
} }
for (auto& iter : *row_iter) { for (auto& iter : *row_iter) {
fputs(iter, outfile); if (anonymize) {
fputs(ta.next(string_fragment::from_c_str(iter)).c_str(), outfile);
} else {
fputs(iter, outfile);
}
} }
fprintf(outfile, "\n"); fprintf(outfile, "\n");
@ -1338,7 +1357,13 @@ com_save_to(exec_context& ec,
continue; continue;
} }
auto sbr = read_res.unwrap(); auto sbr = read_res.unwrap();
fprintf(outfile, "%.*s\n", (int) sbr.length(), sbr.get_data()); if (anonymize) {
auto msg = ta.next(sbr.to_string_fragment().to_string());
fprintf(outfile, "%s\n", msg.c_str());
} else {
fprintf(
outfile, "%.*s\n", (int) sbr.length(), sbr.get_data());
}
line_count += 1; line_count += 1;
} }
@ -1357,6 +1382,9 @@ com_save_to(exec_context& ec,
std::string line; std::string line;
tss->text_value_for_line(*tc, lpc, line, text_sub_source::RF_RAW); tss->text_value_for_line(*tc, lpc, line, text_sub_source::RF_RAW);
if (anonymize) {
line = ta.next(line);
}
fprintf(outfile, "%s\n", line.c_str()); fprintf(outfile, "%s\n", line.c_str());
line_count += 1; line_count += 1;
@ -1376,6 +1404,10 @@ com_save_to(exec_context& ec,
break; break;
} }
tc->listview_value_for_rows(*tc, *iter, rows); tc->listview_value_for_rows(*tc, *iter, rows);
if (anonymize) {
rows[0].al_attrs.clear();
rows[0].al_string = ta.next(rows[0].al_string);
}
write_line_to(outfile, rows[0]); write_line_to(outfile, rows[0]);
auto y = 1_vl; auto y = 1_vl;
@ -5162,6 +5194,7 @@ readline_context::command_t STD_COMMANDS[] = {
help_text(":write-to") help_text(":write-to")
.with_summary("Overwrite the given file with any marked lines in the " .with_summary("Overwrite the given file with any marked lines in the "
"current view") "current view")
.with_parameter(help_text("--anonymize", "Anonymize the lines").optional())
.with_parameter(help_text("path", "The path to the file to write")) .with_parameter(help_text("path", "The path to the file to write"))
.with_tags({"io", "scripting"}) .with_tags({"io", "scripting"})
.with_example( .with_example(
@ -5172,6 +5205,7 @@ readline_context::command_t STD_COMMANDS[] = {
help_text(":write-csv-to") help_text(":write-csv-to")
.with_summary("Write SQL results to the given file in CSV format") .with_summary("Write SQL results to the given file in CSV format")
.with_parameter(help_text("--anonymize", "Anonymize the row contents").optional())
.with_parameter(help_text("path", "The path to the file to write")) .with_parameter(help_text("path", "The path to the file to write"))
.with_tags({"io", "scripting", "sql"}) .with_tags({"io", "scripting", "sql"})
.with_example({"To write SQL results as CSV to /tmp/table.csv", .with_example({"To write SQL results as CSV to /tmp/table.csv",
@ -5181,6 +5215,7 @@ readline_context::command_t STD_COMMANDS[] = {
help_text(":write-json-to") help_text(":write-json-to")
.with_summary("Write SQL results to the given file in JSON format") .with_summary("Write SQL results to the given file in JSON format")
.with_parameter(help_text("--anonymize", "Anonymize the JSON values").optional())
.with_parameter(help_text("path", "The path to the file to write")) .with_parameter(help_text("path", "The path to the file to write"))
.with_tags({"io", "scripting", "sql"}) .with_tags({"io", "scripting", "sql"})
.with_example({"To write SQL results as JSON to /tmp/table.json", .with_example({"To write SQL results as JSON to /tmp/table.json",
@ -5191,6 +5226,7 @@ readline_context::command_t STD_COMMANDS[] = {
help_text(":write-jsonlines-to") help_text(":write-jsonlines-to")
.with_summary( .with_summary(
"Write SQL results to the given file in JSON Lines format") "Write SQL results to the given file in JSON Lines format")
.with_parameter(help_text("--anonymize", "Anonymize the JSON values").optional())
.with_parameter(help_text("path", "The path to the file to write")) .with_parameter(help_text("path", "The path to the file to write"))
.with_tags({"io", "scripting", "sql"}) .with_tags({"io", "scripting", "sql"})
.with_example({"To write SQL results as JSON Lines to /tmp/table.json", .with_example({"To write SQL results as JSON Lines to /tmp/table.json",
@ -5201,6 +5237,7 @@ readline_context::command_t STD_COMMANDS[] = {
help_text(":write-table-to") help_text(":write-table-to")
.with_summary( .with_summary(
"Write SQL results to the given file in a tabular format") "Write SQL results to the given file in a tabular format")
.with_parameter(help_text("--anonymize", "Anonymize the table contents").optional())
.with_parameter(help_text("path", "The path to the file to write")) .with_parameter(help_text("path", "The path to the file to write"))
.with_tags({"io", "scripting", "sql"}) .with_tags({"io", "scripting", "sql"})
.with_example({"To write SQL results as text to /tmp/table.txt", .with_example({"To write SQL results as text to /tmp/table.txt",
@ -5216,6 +5253,7 @@ readline_context::command_t STD_COMMANDS[] = {
.with_parameter(help_text("--view={log,db}", .with_parameter(help_text("--view={log,db}",
"The view to use as the source of data") "The view to use as the source of data")
.optional()) .optional())
.with_parameter(help_text("--anonymize", "Anonymize the lines").optional())
.with_parameter(help_text("path", "The path to the file to write")) .with_parameter(help_text("path", "The path to the file to write"))
.with_tags({"io", "scripting", "sql"}) .with_tags({"io", "scripting", "sql"})
.with_example( .with_example(
@ -5227,6 +5265,7 @@ readline_context::command_t STD_COMMANDS[] = {
help_text(":write-view-to") help_text(":write-view-to")
.with_summary("Write the text in the top view to the given file " .with_summary("Write the text in the top view to the given file "
"without any formatting") "without any formatting")
.with_parameter(help_text("--anonymize", "Anonymize the lines").optional())
.with_parameter(help_text("path", "The path to the file to write")) .with_parameter(help_text("path", "The path to the file to write"))
.with_tags({"io", "scripting", "sql"}) .with_tags({"io", "scripting", "sql"})
.with_example( .with_example(
@ -5237,6 +5276,7 @@ readline_context::command_t STD_COMMANDS[] = {
help_text(":write-screen-to") help_text(":write-screen-to")
.with_summary("Write the displayed text or SQL results to the given " .with_summary("Write the displayed text or SQL results to the given "
"file without any formatting") "file without any formatting")
.with_parameter(help_text("--anonymize", "Anonymize the lines").optional())
.with_parameter(help_text("path", "The path to the file to write")) .with_parameter(help_text("path", "The path to the file to write"))
.with_tags({"io", "scripting", "sql"}) .with_tags({"io", "scripting", "sql"})
.with_example({"To write only the displayed text to /tmp/table.txt", .with_example({"To write only the displayed text to /tmp/table.txt",

@ -104,6 +104,13 @@ public:
return *this; return *this;
} }
array_t to_array() {
array_t retval;
this->h_context.Final(retval.out(0), retval.out(0));
return retval;
}
void to_string(auto_buffer& buf) void to_string(auto_buffer& buf)
{ {
array_t bits; array_t bits;
@ -120,6 +127,14 @@ public:
return bits.to_string(); return bits.to_string();
} }
std::string to_uuid_string()
{
array_t bits;
this->h_context.Final(bits.out(0), bits.out(1));
return bits.to_uuid_string();
}
private: private:
SpookyHash h_context; SpookyHash h_context;
}; };

@ -402,9 +402,10 @@ matcher::matches(uint32_t options)
{ {
this->mb_input.i_next_offset = -1; this->mb_input.i_next_offset = -1;
} else if (this->mb_match_data[0]->empty()) { } else if (this->mb_match_data[0]->empty()) {
this->mb_input.i_next_offset = this->mb_match_data[0]->sf_end + 1; this->mb_input.i_next_offset
= this->mb_match_data.md_ovector[1] + 1;
} else { } else {
this->mb_input.i_next_offset = this->mb_match_data[0]->sf_end; this->mb_input.i_next_offset = this->mb_match_data.md_ovector[1];
} }
this->mb_match_data.md_input.i_next_offset this->mb_match_data.md_input.i_next_offset
= this->mb_input.i_next_offset; = this->mb_input.i_next_offset;

@ -82,7 +82,7 @@ public:
return string_fragment::from_byte_range( return string_fragment::from_byte_range(
this->md_input.i_string.sf_string, this->md_input.i_string.sf_string,
this->md_input.i_next_offset, this->md_input.i_string.sf_begin + this->md_input.i_next_offset,
this->md_input.i_string.sf_end); this->md_input.i_string.sf_end);
} }

@ -34,6 +34,7 @@
#include "scn/scn.h" #include "scn/scn.h"
#include "spookyhash/SpookyV2.h" #include "spookyhash/SpookyV2.h"
#include "sqlite-extension-func.hh" #include "sqlite-extension-func.hh"
#include "text_anonymizer.hh"
#include "vtab_module.hh" #include "vtab_module.hh"
#include "vtab_module_json.hh" #include "vtab_module_json.hh"
#include "yajl/api/yajl_gen.h" #include "yajl/api/yajl_gen.h"
@ -617,6 +618,14 @@ sql_humanize_file_size(file_ssize_t value)
return humanize::file_size(value, humanize::alignment::columnar); return humanize::file_size(value, humanize::alignment::columnar);
} }
std::string
sql_anonymize(string_fragment frag)
{
static safe::Safe<lnav::text_anonymizer> ta;
return ta.writeAccess()->next(frag);
}
int int
string_extension_functions(struct FuncDef** basic_funcs, string_extension_functions(struct FuncDef** basic_funcs,
struct FuncDefAgg** agg_funcs) struct FuncDefAgg** agg_funcs)
@ -729,6 +738,17 @@ string_extension_functions(struct FuncDef** basic_funcs,
"4, 5, 6, 7, 8]')", "4, 5, 6, 7, 8]')",
})), })),
sqlite_func_adapter<decltype(&sql_anonymize), sql_anonymize>::builder(
help_text("anonymize",
"Replace identifying information with random values.")
.sql_function()
.with_parameter({"value", "The text to anonymize"})
.with_tags({"string"})
.with_example({
"To anonymize an IP address",
"SELECT anonymize('Hello, 192.168.1.2')",
})),
sqlite_func_adapter<decltype(&extract), extract>::builder( sqlite_func_adapter<decltype(&extract), extract>::builder(
help_text("extract", help_text("extract",
"Automatically Parse and extract data from a string") "Automatically Parse and extract data from a string")

@ -58,10 +58,6 @@ libtailerservice_a_CPPFLAGS = \
-I$(srcdir)/../third-party \ -I$(srcdir)/../third-party \
-I$(top_srcdir)/src/third-party/scnlib/include -I$(top_srcdir)/src/third-party/scnlib/include
libtailerservice_a_LIBADD = \
libtailercommon.a \
libtailerpp.a
libtailerservice_a_SOURCES = \ libtailerservice_a_SOURCES = \
tailerbin.cc \ tailerbin.cc \
tailer.looper.cc tailer.looper.cc

@ -0,0 +1,514 @@
/**
* Copyright (c) 2022, Timothy Stack
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Timothy Stack nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "text_anonymizer.hh"
#include <arpa/inet.h>
#include <curl/curl.h>
#include "animals-json.h"
#include "config.h"
#include "data_scanner.hh"
#include "diseases-json.h"
#include "ghc/filesystem.hpp"
#include "lnav_util.hh"
#include "pcrepp/pcre2pp.hh"
#include "words-json.h"
#include "yajlpp/yajlpp_def.hh"
namespace lnav {
struct random_list {
std::vector<std::string> rl_data;
std::string at_index(size_t index) const
{
auto counter = index / this->rl_data.size();
auto mod = index % this->rl_data.size();
auto retval = this->rl_data[mod];
if (counter > 0) {
retval = fmt::format(FMT_STRING("{}{}"), retval, counter);
}
return retval;
}
};
static const typed_json_path_container<random_list> random_list_handlers = {
yajlpp::property_handler("data#").for_field(&random_list::rl_data),
};
static random_list
load_word_list()
{
static const intern_string_t name
= intern_string::lookup(words_json.get_name());
auto parse_res
= random_list_handlers.parser_for(name).with_ignore_unused(false).of(
words_json.to_string_fragment());
return parse_res.unwrap();
}
static const random_list&
get_word_list()
{
static const auto retval = load_word_list();
return retval;
}
static random_list
load_animal_list()
{
static const intern_string_t name
= intern_string::lookup(animals_json.get_name());
auto parse_res
= random_list_handlers.parser_for(name).with_ignore_unused(false).of(
animals_json.to_string_fragment());
return parse_res.unwrap();
}
static const random_list&
get_animal_list()
{
static const auto retval = load_animal_list();
return retval;
}
static random_list
load_disease_list()
{
static const intern_string_t name
= intern_string::lookup(diseases_json.get_name());
auto parse_res
= random_list_handlers.parser_for(name).with_ignore_unused(false).of(
diseases_json.to_string_fragment());
return parse_res.unwrap();
}
static const random_list&
get_disease_list()
{
static const auto retval = load_disease_list();
return retval;
}
std::string
text_anonymizer::next(string_fragment line)
{
data_scanner ds(line);
std::string retval;
while (true) {
auto tok_res = ds.tokenize2();
if (!tok_res) {
break;
}
switch (tok_res->tr_token) {
case DT_URL: {
auto url_str = tok_res->to_string();
auto* cu = curl_url();
if (curl_url_set(cu, CURLUPART_URL, url_str.c_str(), 0)
!= CURLUE_OK)
{
retval += "<unparseable-url>";
} else {
auto_mem<char> url_part(curl_free);
if (curl_url_get(
cu, CURLUPART_USER, url_part.out(), CURLU_URLDECODE)
== CURLUE_OK)
{
auto anon_user = this->get_default(
this->ta_user_names,
url_part.in(),
[](size_t size, auto& user) {
return get_animal_list().at_index(size);
});
curl_url_set(cu,
CURLUPART_USER,
anon_user.c_str(),
CURLU_URLENCODE);
}
if (curl_url_get(cu,
CURLUPART_PASSWORD,
url_part.out(),
CURLU_URLDECODE)
== CURLUE_OK)
{
auto anon_pass
= hasher()
.update(url_part.in(), strlen(url_part.in()))
.to_string();
curl_url_set(cu,
CURLUPART_PASSWORD,
anon_pass.c_str(),
CURLU_URLENCODE);
}
if (curl_url_get(
cu, CURLUPART_HOST, url_part.out(), CURLU_URLDECODE)
== CURLUE_OK)
{
auto anon_host = this->get_default(
this->ta_host_names,
url_part.in(),
[](size_t size, auto& hn) {
const auto& diseases = get_disease_list();
return fmt::format(FMT_STRING("{}.example.com"),
diseases.at_index(size));
});
curl_url_set(cu,
CURLUPART_HOST,
anon_host.c_str(),
CURLU_URLENCODE);
}
if (curl_url_get(
cu, CURLUPART_PATH, url_part.out(), CURLU_URLDECODE)
== CURLUE_OK)
{
ghc::filesystem::path url_path(url_part.in());
ghc::filesystem::path anon_path;
for (const auto& comp : url_path) {
if (comp == comp.root_path()) {
anon_path = anon_path / comp;
continue;
}
anon_path = anon_path / this->next(comp.string());
}
curl_url_set(cu,
CURLUPART_PATH,
anon_path.c_str(),
CURLU_URLENCODE);
}
if (curl_url_get(cu,
CURLUPART_QUERY,
url_part.out(),
CURLU_URLDECODE)
== CURLUE_OK)
{
static const auto SPLIT_RE
= lnav::pcre2pp::code::from_const(R"((&))");
curl_url_set(cu, CURLUPART_QUERY, nullptr, 0);
auto url_query
= string_fragment::from_c_str(url_part.in());
auto replacer = [this, cu](const std::string& comp) {
std::string anon_query;
auto eq_index = comp.find('=');
if (eq_index != std::string::npos) {
anon_query = fmt::format(
FMT_STRING("{}={}"),
this->next(comp.substr(0, eq_index)),
this->next(comp.substr(eq_index + 1)));
} else {
anon_query = this->next(comp);
}
curl_url_set(cu,
CURLUPART_QUERY,
anon_query.c_str(),
CURLU_URLENCODE | CURLU_APPENDQUERY);
};
auto loop_res
= SPLIT_RE.capture_from(url_query).for_each(
[&replacer](lnav::pcre2pp::match_data& md) {
replacer(md.leading().to_string());
});
if (loop_res.isOk()) {
replacer(loop_res.unwrap().to_string());
}
}
if (curl_url_get(cu,
CURLUPART_FRAGMENT,
url_part.out(),
CURLU_URLDECODE)
== CURLUE_OK)
{
auto anon_frag = this->next(
string_fragment::from_c_str(url_part.in()));
curl_url_set(cu,
CURLUPART_FRAGMENT,
anon_frag.c_str(),
CURLU_URLENCODE);
}
auto_mem<char> anon_url(curl_free);
if (curl_url_get(cu, CURLUPART_URL, anon_url.out(), 0)
== CURLUE_OK)
{
retval.append(anon_url.in());
}
}
break;
}
case DT_PATH: {
ghc::filesystem::path inp_path(tok_res->to_string());
ghc::filesystem::path anon_path;
for (const auto& comp : inp_path) {
auto comp_str = comp.string();
if (comp == comp.root_path() || comp == inp_path) {
anon_path = anon_path / comp;
continue;
}
anon_path = anon_path / this->next(comp_str);
}
retval += anon_path.string();
break;
}
case DT_CREDIT_CARD_NUMBER: {
auto cc = tok_res->to_string();
auto has_spaces = cc.size() > 16;
auto new_end = std::remove_if(
cc.begin(), cc.end(), [](auto ch) { return ch == ' '; });
cc.erase(new_end, cc.end());
auto anon_cc = hasher().update(cc).to_string().substr(0, 16);
if (has_spaces) {
anon_cc.insert(12, " ");
anon_cc.insert(8, " ");
anon_cc.insert(4, " ");
}
retval += anon_cc;
break;
}
case DT_MAC_ADDRESS: {
// 00-00-5E-00-53-00
auto mac_addr = tok_res->to_string();
retval += this->get_default(
this->ta_mac_addresses,
mac_addr,
[](size_t size, auto& inp) {
uint32_t base_mac = 0x5e005300;
base_mac += size;
auto anon_mac = byte_array<6>::from({
0x00,
0x00,
(unsigned char) ((base_mac >> 24) & 0xff),
(unsigned char) ((base_mac >> 16) & 0xff),
(unsigned char) ((base_mac >> 8) & 0xff),
(unsigned char) ((base_mac >> 0) & 0xff),
});
return anon_mac.to_string(
nonstd::make_optional(inp[2]));
});
break;
}
case DT_HEX_DUMP: {
auto hex_str = tok_res->to_string();
auto hash_str = hasher().update(hex_str).to_array().to_string(
nonstd::make_optional(hex_str[2]));
std::string anon_hex;
while (anon_hex.size() < hex_str.size()) {
anon_hex += hash_str;
}
anon_hex.resize(hex_str.size());
retval += anon_hex;
break;
}
case DT_IPV4_ADDRESS: {
auto ipv4 = tok_res->to_string();
retval += this->get_default(
this->ta_ipv4_addresses, ipv4, [](size_t size, auto& _) {
char anon_ipv4[INET_ADDRSTRLEN];
struct in_addr ia;
inet_aton("10.0.0.0", &ia);
ia.s_addr = htonl(ntohl(ia.s_addr) + 1 + size);
inet_ntop(AF_INET, &ia, anon_ipv4, sizeof(anon_ipv4));
return std::string{anon_ipv4};
});
break;
}
case DT_IPV6_ADDRESS: {
auto ipv6 = tok_res->to_string();
retval += this->get_default(
this->ta_ipv6_addresses, ipv6, [](size_t size, auto& _) {
char anon_ipv6[INET6_ADDRSTRLEN];
struct in6_addr ia;
uint32_t* ia6_addr32 = (uint32_t*) &ia.s6_addr[12];
inet_pton(AF_INET6, "2001:db8::", &ia);
*ia6_addr32 = htonl(ntohl(*ia6_addr32) + 1 + size);
inet_ntop(AF_INET6, &ia, anon_ipv6, sizeof(anon_ipv6));
return std::string{anon_ipv6};
});
break;
}
case DT_EMAIL: {
auto email_addr = tok_res->to_string();
auto at_index = email_addr.find('@');
retval += fmt::format(
FMT_STRING("{}@{}.example.com"),
this->get_default(this->ta_user_names,
email_addr.substr(0, at_index),
[](auto size, const auto& inp) {
return get_animal_list().at_index(
size);
}),
this->get_default(this->ta_host_names,
email_addr.substr(at_index + 1),
[](auto size, const auto& inp) {
return get_disease_list().at_index(
size);
}));
break;
}
case DT_WORD:
case DT_SYMBOL: {
static const auto SPLIT_RE = lnav::pcre2pp::code::from_const(
R"((\.|::|_|-|/|\\|\d+))");
auto symbol_frag = ds.to_string_fragment(tok_res->tr_capture);
auto sym_provider = [](auto size, const auto& inp) {
if (inp.size() <= 4) {
return inp;
}
auto comp_frag = string_fragment::from_str(inp);
return string_fragment::from_str(
get_word_list().at_index(size))
.to_string_with_case_style(
comp_frag.detect_text_case_style());
};
auto cap_res
= SPLIT_RE.capture_from(symbol_frag)
.for_each([this, &retval, &sym_provider](
lnav::pcre2pp::match_data& md) {
auto comp = md.leading().to_string();
retval
+= this->get_default(
this->ta_symbols, comp, sym_provider)
+ md[0]->to_string();
});
if (cap_res.isErr()) {
retval += "<symbol>";
} else {
auto remaining = cap_res.unwrap().to_string();
retval += this->get_default(
this->ta_symbols, remaining, sym_provider);
}
break;
}
case DT_QUOTED_STRING: {
auto anon_inner = this->next(
ds.to_string_fragment(tok_res->tr_inner_capture)
.to_string());
retval += line.sub_range(tok_res->tr_capture.c_begin,
tok_res->tr_inner_capture.c_begin)
.to_string()
+ anon_inner
+ ds.to_string_fragment(tok_res->tr_capture).back();
break;
}
case DT_XML_OPEN_TAG: {
auto open_tag = tok_res->to_string();
auto space_index = open_tag.find(' ');
if (space_index == std::string::npos) {
retval += open_tag;
} else {
static const auto ATTR_RE
= lnav::pcre2pp::code::from_const(R"([\w\-]+=)");
auto remaining = string_fragment::from_str_range(
open_tag, space_index, open_tag.size());
auto md = ATTR_RE.create_match_data();
retval += open_tag.substr(0, space_index + 1);
while (!remaining.empty()) {
auto cap_res = ATTR_RE.capture_from(remaining)
.into(md)
.matches()
.ignore_error();
if (!cap_res) {
break;
}
retval += md.leading();
retval += md[0]->to_string();
remaining = md.remaining();
data_scanner ds(remaining);
auto attr_tok_res = ds.tokenize2();
if (!attr_tok_res) {
continue;
}
retval += this->next(attr_tok_res->to_string());
remaining = remaining.substr(
attr_tok_res->tr_capture.length());
}
retval += remaining.to_string();
}
break;
}
case DT_UUID: {
retval
+= hasher().update(tok_res->to_string()).to_uuid_string();
break;
}
default: {
retval += tok_res->to_string();
break;
}
}
}
return retval;
}
} // namespace lnav

@ -0,0 +1,75 @@
/**
* Copyright (c) 2022, Timothy Stack
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Timothy Stack nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lnav_text_anonymizer_hh
#define lnav_text_anonymizer_hh
#include <string>
#include <vector>
#include "base/intern_string.hh"
#include "robin_hood/robin_hood.h"
namespace lnav {
class text_anonymizer {
public:
text_anonymizer() = default;
std::string next(string_fragment line);
private:
template<typename F>
const std::string& get_default(
robin_hood::unordered_map<std::string, std::string>& mapping,
const std::string& input,
F provider)
{
auto iter = mapping.find(input);
if (iter == mapping.end()) {
auto emp_res = mapping.template emplace(
input, provider(mapping.size(), input));
iter = emp_res.first;
}
return iter->second;
}
robin_hood::unordered_map<std::string, std::string> ta_mac_addresses;
robin_hood::unordered_map<std::string, std::string> ta_ipv4_addresses;
robin_hood::unordered_map<std::string, std::string> ta_ipv6_addresses;
robin_hood::unordered_map<std::string, std::string> ta_user_names;
robin_hood::unordered_map<std::string, std::string> ta_host_names;
robin_hood::unordered_map<std::string, std::string> ta_symbols;
};
} // namespace lnav
#endif

File diff suppressed because one or more lines are too long

@ -573,16 +573,19 @@ struct json_path_handler : public json_path_handler_base {
template<typename T, typename... Args> template<typename T, typename... Args>
struct LastIsVector { struct LastIsVector {
using value_type = typename LastIsVector<Args...>::value_type;
static constexpr bool value = LastIsVector<Args...>::value; static constexpr bool value = LastIsVector<Args...>::value;
}; };
template<typename T, typename U> template<typename T, typename U>
struct LastIsVector<std::vector<U> T::*> { struct LastIsVector<std::vector<U> T::*> {
using value_type = U;
static constexpr bool value = true; static constexpr bool value = true;
}; };
template<typename T, typename U> template<typename T, typename U>
struct LastIsVector<U T::*> { struct LastIsVector<U T::*> {
using value_type = void;
static constexpr bool value = false; static constexpr bool value = false;
}; };
@ -641,8 +644,41 @@ struct json_path_handler : public json_path_handler_base {
return *this; return *this;
} }
template<
typename... Args,
std::enable_if_t<LastIs<std::vector<std::string>, Args...>::value, bool>
= true>
json_path_handler& for_field(Args... args)
{
this->add_cb(str_field_cb2);
this->jph_str_cb = [args...](yajlpp_parse_context* ypc,
const unsigned char* str,
size_t len) {
auto obj = ypc->ypc_obj_stack.top();
auto value_str = std::string((const char*) str, len);
auto jph = ypc->ypc_current_handler;
if (jph->jph_pattern) {
if (!jph->jph_pattern->find_in(value_str).ignore_error()) {
jph->report_pattern_error(ypc, value_str);
}
}
json_path_handler::get_field(obj, args...)
.emplace_back(std::move(value_str));
return 1;
};
return *this;
}
template<typename... Args, template<typename... Args,
std::enable_if_t<LastIsVector<Args...>::value, bool> = true> std::enable_if_t<LastIsVector<Args...>::value, bool> = true,
std::enable_if_t<
!std::is_same<typename LastIsVector<Args...>::value_type,
std::string>::value,
bool>
= true>
json_path_handler& for_field(Args... args) json_path_handler& for_field(Args... args)
{ {
this->jph_obj_provider this->jph_obj_provider

@ -64,6 +64,11 @@ add_executable(test_top_status test_top_status.cc test_stubs.cc)
target_link_libraries(test_top_status diag logfmt) target_link_libraries(test_top_status diag logfmt)
add_test(NAME test_top_status COMMAND test_top_status) add_test(NAME test_top_status COMMAND test_top_status)
add_executable(test_text_anonymizer test_text_anonymizer.cc test_stubs.cc)
target_include_directories(test_text_anonymizer PUBLIC ../src/third-party/doctest-root)
target_link_libraries(test_text_anonymizer diag)
add_test(NAME test_text_anonymizer COMMAND test_text_anonymizer)
add_executable(drive_view_colors drive_view_colors.cc test_stubs.cc) add_executable(drive_view_colors drive_view_colors.cc test_stubs.cc)
target_link_libraries(drive_view_colors diag) target_link_libraries(drive_view_colors diag)

@ -76,6 +76,7 @@ check_PROGRAMS = \
test_log_accel \ test_log_accel \
test_ncurses_unicode \ test_ncurses_unicode \
test_reltime \ test_reltime \
test_text_anonymizer \
test_top_status test_top_status
AM_LDFLAGS = \ AM_LDFLAGS = \
@ -136,6 +137,8 @@ test_line_buffer2_SOURCES = test_line_buffer2.cc
test_log_accel_SOURCES = test_log_accel.cc test_log_accel_SOURCES = test_log_accel.cc
test_text_anonymizer_SOURCES = test_text_anonymizer.cc
test_top_status_SOURCES = test_top_status.cc test_top_status_SOURCES = test_top_status.cc
test_abbrev_SOURCES = test_abbrev.cc test_abbrev_SOURCES = test_abbrev.cc
@ -416,6 +419,7 @@ TESTS = \
test_sql_views_vtab.sh \ test_sql_views_vtab.sh \
test_sql_xml_func.sh \ test_sql_xml_func.sh \
test_sql_yaml_func.sh \ test_sql_yaml_func.sh \
test_text_anonymizer \
test_text_file.sh \ test_text_file.sh \
test_tui.sh \ test_tui.sh \
test_data_parser.sh \ test_data_parser.sh \

@ -0,0 +1,88 @@
2022-06-02T12:26:22.072Z info vpxd[47413] [Originator@6876 sub=vpxLro opID=21fa61e9-3e] [VpxLRO] -- BEGIN lro-954041 -- AuthorizationManager -- vim.AuthorizationManager.hasUserPrivilegeOnEntities -- 52768da7-4006-3d4a-4917-ee027373630f(522e0475-8901-e8b8-1eb8-07ec729ac50c)
key 23:23 ^
sym 23:24 ^ Z
pair 23:24 ^ Z
key 30:30 ^
sym 30:34 ^--^ vpxd
pair 30:34 ^--^ vpxd
key 35:35 ^
num 35:40 ^---^ 47413
val 35:40 ^---^ 47413
grp 35:40 ^---^ 47413
pair 35:40 ^---^ 47413
key 43:43 ^
key 43:62 ^-----------------^ Originator@6876 sub
sym 63:69 ^----^ vpxLro
val 63:69 ^----^ vpxLro
pair 43:69 ^------------------------^ Originator@6876 sub=vpxLro
key 70:74 ^--^ opID
sym 75:86 ^---------^ 21fa61e9-3e
val 75:86 ^---------^ 21fa61e9-3e
pair 70:86 ^--------------^ opID=21fa61e9-3e
grp 43:86 ^-----------------------------------------^ Originator@6876 sub=vpxLro opID=21fa61e9-3e
pair 43:86 ^-----------------------------------------^ Originator@6876 sub=vpxLro opID=21fa61e9-3e
key 89:89 ^
sym 89:95 ^----^ VpxLRO
val 89:95 ^----^ VpxLRO
grp 89:95 ^----^ VpxLRO
pair 89:95 ^----^ VpxLRO
key 97:97 ^
sym 97:99 ^^ --
pair 97:99 ^^ --
key 100:100 ^
sym 100:105 ^---^ BEGIN
pair 100:105 ^---^ BEGIN
key 106:106 ^
sym 106:116 ^--------^ lro-954041
pair 106:116 ^--------^ lro-954041
key 117:117 ^
sym 117:119 ^^ --
pair 117:119 ^^ --
key 120:120 ^
sym 120:140 ^------------------^ AuthorizationManager
pair 120:140 ^------------------^ AuthorizationManager
key 141:141 ^
sym 141:143 ^^ --
pair 141:143 ^^ --
key 144:144 ^
sym 144:195 ^-------------------------------------------------^ vim.AuthorizationManager.hasUserPrivilegeOnEntities
pair 144:195 ^-------------------------------------------------^ vim.AuthorizationManager.hasUserPrivilegeOnEntities
key 196:196 ^
sym 196:198 ^^ --
pair 196:198 ^^ --
key 199:199 ^
uuid 199:235 ^----------------------------------^ 52768da7-4006-3d4a-4917-ee027373630f
pair 199:235 ^----------------------------------^ 52768da7-4006-3d4a-4917-ee027373630f
key 236:236 ^
uuid 236:272 ^----------------------------------^ 522e0475-8901-e8b8-1eb8-07ec729ac50c
val 236:272 ^----------------------------------^ 522e0475-8901-e8b8-1eb8-07ec729ac50c
grp 236:272 ^----------------------------------^ 522e0475-8901-e8b8-1eb8-07ec729ac50c
pair 236:272 ^----------------------------------^ 522e0475-8901-e8b8-1eb8-07ec729ac50c
msg :2022-06-02T12:26:22.072Z info vpxd[47413] [Originator@6876 sub=vpxLro opID=21fa61e9-3e] [VpxLRO] -- BEGIN lro-954041 -- AuthorizationManager -- vim.AuthorizationManager.hasUserPrivilegeOnEntities -- 52768da7-4006-3d4a-4917-ee027373630f(522e0475-8901-e8b8-1eb8-07ec729ac50c)
format :2022-06-02T12:26:22.072# info #[#] [#] [#] # # # # # # # # #(#)
{
"col_0": "Z",
"col_1": "vpxd",
"col_2": [
47413
],
"col_3": {
"Originator@6876 sub": "vpxLro",
"opID": "21fa61e9-3e"
},
"col_4": [
"VpxLRO"
],
"col_5": "--",
"col_6": "BEGIN",
"col_7": "lro-954041",
"col_8": "--",
"col_9": "AuthorizationManager",
"col_10": "--",
"col_11": "vim.AuthorizationManager.hasUserPrivilegeOnEntities",
"col_12": "--",
"col_13": "52768da7-4006-3d4a-4917-ee027373630f",
"col_14": [
"522e0475-8901-e8b8-1eb8-07ec729ac50c"
]
}

@ -56,6 +56,7 @@ main(int argc, char* argv[])
{ {
int c, retval = EXIT_SUCCESS; int c, retval = EXIT_SUCCESS;
bool prompt = false, is_log = false, pretty_print = false; bool prompt = false, is_log = false, pretty_print = false;
bool scanner_details = false;
{ {
static auto builtin_formats static auto builtin_formats
@ -75,7 +76,7 @@ main(int argc, char* argv[])
load_formats(paths, errors); load_formats(paths, errors);
} }
while ((c = getopt(argc, argv, "pPl")) != -1) { while ((c = getopt(argc, argv, "pPls")) != -1) {
switch (c) { switch (c) {
case 'p': case 'p':
prompt = true; prompt = true;
@ -89,6 +90,10 @@ main(int argc, char* argv[])
is_log = true; is_log = true;
break; break;
case 's':
scanner_details = true;
break;
default: default:
retval = EXIT_FAILURE; retval = EXIT_FAILURE;
break; break;
@ -191,6 +196,52 @@ main(int argc, char* argv[])
data_parser::TRACE_FILE = fopen("scanned.dpt", "w"); data_parser::TRACE_FILE = fopen("scanned.dpt", "w");
data_scanner ds(sub_line, body.lr_start); data_scanner ds(sub_line, body.lr_start);
if (scanner_details) {
fprintf(out,
" %s\n",
ds.get_input().to_string().c_str());
while (true) {
auto tok_res = ds.tokenize2();
if (!tok_res) {
break;
}
fprintf(out,
"%4s %3d:%-3d ",
data_scanner::token2name(tok_res->tr_token),
tok_res->tr_capture.c_begin,
tok_res->tr_capture.c_end);
size_t cap_index = 0;
for (; cap_index < tok_res->tr_capture.c_end;
cap_index++)
{
if (cap_index == tok_res->tr_capture.c_begin) {
fputc('^', out);
} else if (cap_index
== (tok_res->tr_capture.c_end - 1))
{
fputc('^', out);
} else if (cap_index > tok_res->tr_capture.c_begin)
{
fputc('-', out);
} else {
fputc(' ', out);
}
}
for (; cap_index < (int) ds.get_input().length();
cap_index++)
{
fputc(' ', out);
}
auto sub = tok_res->to_string();
fprintf(out, " %s\n", sub.c_str());
}
}
ds.reset();
data_parser dp(&ds); data_parser dp(&ds);
std::string msg_format; std::string msg_format;

@ -112,9 +112,7 @@ int
main(int argc, char* argv[]) main(int argc, char* argv[])
{ {
int retval = EXIT_SUCCESS; int retval = EXIT_SUCCESS;
const char* errptr;
auto_fd fd; auto_fd fd;
int eoff;
if (argc < 3) { if (argc < 3) {
fprintf(stderr, "error: expecting pattern and file arguments\n"); fprintf(stderr, "error: expecting pattern and file arguments\n");

@ -54,6 +54,8 @@ EXPECTED_FILES = \
$(srcdir)/%reldir%/test_cmds.sh_2de9ec294e2f533d13e04c70d9525f8b58d47bb2.out \ $(srcdir)/%reldir%/test_cmds.sh_2de9ec294e2f533d13e04c70d9525f8b58d47bb2.out \
$(srcdir)/%reldir%/test_cmds.sh_2e123104cdd2087ac40731a0aa533ba6a87ea744.err \ $(srcdir)/%reldir%/test_cmds.sh_2e123104cdd2087ac40731a0aa533ba6a87ea744.err \
$(srcdir)/%reldir%/test_cmds.sh_2e123104cdd2087ac40731a0aa533ba6a87ea744.out \ $(srcdir)/%reldir%/test_cmds.sh_2e123104cdd2087ac40731a0aa533ba6a87ea744.out \
$(srcdir)/%reldir%/test_cmds.sh_2e67bdbbc9a14aa772b2a9f755ed8f8124708558.err \
$(srcdir)/%reldir%/test_cmds.sh_2e67bdbbc9a14aa772b2a9f755ed8f8124708558.out \
$(srcdir)/%reldir%/test_cmds.sh_2ff0fe712c9b0012e42282c5f77b0b83cad37ddf.err \ $(srcdir)/%reldir%/test_cmds.sh_2ff0fe712c9b0012e42282c5f77b0b83cad37ddf.err \
$(srcdir)/%reldir%/test_cmds.sh_2ff0fe712c9b0012e42282c5f77b0b83cad37ddf.out \ $(srcdir)/%reldir%/test_cmds.sh_2ff0fe712c9b0012e42282c5f77b0b83cad37ddf.out \
$(srcdir)/%reldir%/test_cmds.sh_305b1dfdfe785b945df4220aad6671ae1d364f55.err \ $(srcdir)/%reldir%/test_cmds.sh_305b1dfdfe785b945df4220aad6671ae1d364f55.err \
@ -192,6 +194,8 @@ EXPECTED_FILES = \
$(srcdir)/%reldir%/test_cmds.sh_dbdd62995fdefc8318053af05a32416eccfa79fc.out \ $(srcdir)/%reldir%/test_cmds.sh_dbdd62995fdefc8318053af05a32416eccfa79fc.out \
$(srcdir)/%reldir%/test_cmds.sh_dd41fbbcd71699314af232156d4155fbdf849131.err \ $(srcdir)/%reldir%/test_cmds.sh_dd41fbbcd71699314af232156d4155fbdf849131.err \
$(srcdir)/%reldir%/test_cmds.sh_dd41fbbcd71699314af232156d4155fbdf849131.out \ $(srcdir)/%reldir%/test_cmds.sh_dd41fbbcd71699314af232156d4155fbdf849131.out \
$(srcdir)/%reldir%/test_cmds.sh_df6f4cea16bb8f20e6408fe4b40335e6de8a7f18.err \
$(srcdir)/%reldir%/test_cmds.sh_df6f4cea16bb8f20e6408fe4b40335e6de8a7f18.out \
$(srcdir)/%reldir%/test_cmds.sh_e495cf059477e3f80c3241c6f8d5808b6f1d19c7.err \ $(srcdir)/%reldir%/test_cmds.sh_e495cf059477e3f80c3241c6f8d5808b6f1d19c7.err \
$(srcdir)/%reldir%/test_cmds.sh_e495cf059477e3f80c3241c6f8d5808b6f1d19c7.out \ $(srcdir)/%reldir%/test_cmds.sh_e495cf059477e3f80c3241c6f8d5808b6f1d19c7.out \
$(srcdir)/%reldir%/test_cmds.sh_e7e8244fac65bc51dbd5af31be476fe3b8776bfc.err \ $(srcdir)/%reldir%/test_cmds.sh_e7e8244fac65bc51dbd5af31be476fe3b8776bfc.err \
@ -210,8 +214,6 @@ EXPECTED_FILES = \
$(srcdir)/%reldir%/test_cmds.sh_ff6faebbde8586e04bfadba14a3d2bb4451784ad.out \ $(srcdir)/%reldir%/test_cmds.sh_ff6faebbde8586e04bfadba14a3d2bb4451784ad.out \
$(srcdir)/%reldir%/test_config.sh_2765ea0d4c037b8c935840604edb0ae796c97a04.err \ $(srcdir)/%reldir%/test_config.sh_2765ea0d4c037b8c935840604edb0ae796c97a04.err \
$(srcdir)/%reldir%/test_config.sh_2765ea0d4c037b8c935840604edb0ae796c97a04.out \ $(srcdir)/%reldir%/test_config.sh_2765ea0d4c037b8c935840604edb0ae796c97a04.out \
$(srcdir)/%reldir%/test_config.sh_5105c29004e297521310ca0bd0fd560b01c2c549.err \
$(srcdir)/%reldir%/test_config.sh_5105c29004e297521310ca0bd0fd560b01c2c549.out \
$(srcdir)/%reldir%/test_config.sh_5fd9fbccc35e9b06abdd913da0c16bdb306b926e.err \ $(srcdir)/%reldir%/test_config.sh_5fd9fbccc35e9b06abdd913da0c16bdb306b926e.err \
$(srcdir)/%reldir%/test_config.sh_5fd9fbccc35e9b06abdd913da0c16bdb306b926e.out \ $(srcdir)/%reldir%/test_config.sh_5fd9fbccc35e9b06abdd913da0c16bdb306b926e.out \
$(srcdir)/%reldir%/test_config.sh_a0907769aba112d628e7ebe39c4ec252e5e0bc69.err \ $(srcdir)/%reldir%/test_config.sh_a0907769aba112d628e7ebe39c4ec252e5e0bc69.err \
@ -240,12 +242,8 @@ EXPECTED_FILES = \
$(srcdir)/%reldir%/test_events.sh_ed8dc44add223341c03ccb7b3e18371bdb42b710.out \ $(srcdir)/%reldir%/test_events.sh_ed8dc44add223341c03ccb7b3e18371bdb42b710.out \
$(srcdir)/%reldir%/test_format_loader.sh_15e861d2327512a721fd42ae51dc5427689e0bb6.err \ $(srcdir)/%reldir%/test_format_loader.sh_15e861d2327512a721fd42ae51dc5427689e0bb6.err \
$(srcdir)/%reldir%/test_format_loader.sh_15e861d2327512a721fd42ae51dc5427689e0bb6.out \ $(srcdir)/%reldir%/test_format_loader.sh_15e861d2327512a721fd42ae51dc5427689e0bb6.out \
$(srcdir)/%reldir%/test_format_loader.sh_3f1d6f35e8a9ae4fd3e91ffaa82a037b5a847ab7.err \
$(srcdir)/%reldir%/test_format_loader.sh_3f1d6f35e8a9ae4fd3e91ffaa82a037b5a847ab7.out \
$(srcdir)/%reldir%/test_format_loader.sh_5992e2695b7e6cf1f3520dbb87af8fc2b8f27088.err \ $(srcdir)/%reldir%/test_format_loader.sh_5992e2695b7e6cf1f3520dbb87af8fc2b8f27088.err \
$(srcdir)/%reldir%/test_format_loader.sh_5992e2695b7e6cf1f3520dbb87af8fc2b8f27088.out \ $(srcdir)/%reldir%/test_format_loader.sh_5992e2695b7e6cf1f3520dbb87af8fc2b8f27088.out \
$(srcdir)/%reldir%/test_format_loader.sh_a47f2b090a5d8a226783835c7ff7d1c8821f11ed.err \
$(srcdir)/%reldir%/test_format_loader.sh_a47f2b090a5d8a226783835c7ff7d1c8821f11ed.out \
$(srcdir)/%reldir%/test_format_loader.sh_fca6c1fb9f3aaa69b3ffb2d1a8a86434b2f4a247.err \ $(srcdir)/%reldir%/test_format_loader.sh_fca6c1fb9f3aaa69b3ffb2d1a8a86434b2f4a247.err \
$(srcdir)/%reldir%/test_format_loader.sh_fca6c1fb9f3aaa69b3ffb2d1a8a86434b2f4a247.out \ $(srcdir)/%reldir%/test_format_loader.sh_fca6c1fb9f3aaa69b3ffb2d1a8a86434b2f4a247.out \
$(srcdir)/%reldir%/test_json_format.sh_168cac40c27f547044c89d39eb0ff2ef81da4b21.err \ $(srcdir)/%reldir%/test_json_format.sh_168cac40c27f547044c89d39eb0ff2ef81da4b21.err \
@ -744,6 +742,8 @@ EXPECTED_FILES = \
$(srcdir)/%reldir%/test_sql_str_func.sh_04712488fe50554eb36d3ced80f9a033602f3daa.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_04712488fe50554eb36d3ced80f9a033602f3daa.out \
$(srcdir)/%reldir%/test_sql_str_func.sh_11bcc5d32eabbedb6974f160dace9ef1ef0009e9.err \ $(srcdir)/%reldir%/test_sql_str_func.sh_11bcc5d32eabbedb6974f160dace9ef1ef0009e9.err \
$(srcdir)/%reldir%/test_sql_str_func.sh_11bcc5d32eabbedb6974f160dace9ef1ef0009e9.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_11bcc5d32eabbedb6974f160dace9ef1ef0009e9.out \
$(srcdir)/%reldir%/test_sql_str_func.sh_11d458fdadd00df1239a0eeaac049abb49ed212d.err \
$(srcdir)/%reldir%/test_sql_str_func.sh_11d458fdadd00df1239a0eeaac049abb49ed212d.out \
$(srcdir)/%reldir%/test_sql_str_func.sh_129e58679e72f3cc5864812026e49a7917baf3d0.err \ $(srcdir)/%reldir%/test_sql_str_func.sh_129e58679e72f3cc5864812026e49a7917baf3d0.err \
$(srcdir)/%reldir%/test_sql_str_func.sh_129e58679e72f3cc5864812026e49a7917baf3d0.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_129e58679e72f3cc5864812026e49a7917baf3d0.out \
$(srcdir)/%reldir%/test_sql_str_func.sh_151a0fd71ef6837c8cbd8a67e315019b5812b079.err \ $(srcdir)/%reldir%/test_sql_str_func.sh_151a0fd71ef6837c8cbd8a67e315019b5812b079.err \

@ -1,6 +1,6 @@
✘ error: expecting file name or '-' to write to the terminal ✘ error: expecting file name or '-' to write to the terminal
 --> command-option:1  --> command-option:1
 | :write-to   | :write-to 
 = help: :write-to path  = help: :write-to [--anonymize] path
══════════════════════════════════════════════════════════════════════ ══════════════════════════════════════════════════════════════════════
Overwrite the given file with any marked lines in the current view Overwrite the given file with any marked lines in the current view

@ -0,0 +1,23 @@
Apr 7 00:49:42 Tim-Abaft-iMac abashed[0]: Aberrant [abhorrent5701Aberrant]: Link up on en0, 1-Aboard, Full-abortive, Abounding flow-abrupt, Absent [796d,2301,0de1,0300,cde1,3800]
Apr 7 05:49:53 Tim-Abaft-iMac.absorbing Abstracted[17212]: -[absurd abundant] absurd abusive accept: <acceptable:0x511f30
accessible=<KSOmahaServer:0x510d80>
url="https://achondroplasia.example.com/account/accurate2"
achiever=0
acid=1
acidic=1
acoustic=1
body=
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<o:gupdate xmlns:o="http://acinetobacter-infections.example.com/accurate2/acrid" protocol="2.0" version="Act-1.2.0.7709" ismachine="1" requestid="{1ca0a968-cbe9-e75b-d00b-4859609878ea}">
<o:os platform="mac" version="activity" sp="10.10.2_x86_64h"></o:os>
<o:app appid="com.actually.Ad hoc" version="1.2.0.7709" lang="en-us" installage="180" brand="GGLG">
<o:ping r="1" a="1"></o:ping>
<o:updatecheck></o:updatecheck>
</o:app>
</o:gupdate>
>
Apr 7 07:31:56 Tim-Abaft-iMac.absorbing Add[36403]: ADDICTED: The Adhesive adjoining adjustment is admit 10.9.2 adorable of 10.10.2. Use advice's afford afraid to get afterthought aggressive agonizing agree
Call agreement:
Apr 7 07:31:56 Tim-Abaft-iMac.absorbing Add[36403]: 0 Ahead 0x00007fff8a9b3d9b ___Adhesive_Air_airplane_airport + 113
Apr 7 07:31:56 Tim-Abaft-iMac.absorbing Add[36403]: 1 ajar.alarm 0x00007fff8bc84c13 _alcoholic_alert_alike + 8
Apr 7 07:32:56 Tim-Abaft-iMac.absorbing alive[234]: Bad data { abc, 123, 456 )}]

@ -1,6 +1,6 @@
✘ error: write-json-to -- unavailable in secure mode ✘ error: write-json-to -- unavailable in secure mode
 --> command-option:2  --> command-option:2
 | :write-json-to /tmp/bad   | :write-json-to /tmp/bad 
 = help: :write-json-to path  = help: :write-json-to [--anonymize] path
══════════════════════════════════════════════════════════════════════ ══════════════════════════════════════════════════════════════════════
Write SQL results to the given file in JSON format Write SQL results to the given file in JSON format

@ -1565,11 +1565,12 @@ For support questions, email:
:write-table-to path :write-table-to [--anonymize] path
══════════════════════════════════════════════════════════════════════ ══════════════════════════════════════════════════════════════════════
Write SQL results to the given file in a tabular format Write SQL results to the given file in a tabular format
Parameter Parameters
path The path to the file to write --anonymize Anonymize the table contents
path The path to the file to write
See Also See Also
:alt-msg, :append-to, :create-logline-table, :create-search-table, :alt-msg, :append-to, :create-logline-table, :create-search-table,
:echo, :echo, :eval, :export-session-to, :export-session-to, :echo, :echo, :eval, :export-session-to, :export-session-to,
@ -1586,11 +1587,12 @@ For support questions, email:
:write-csv-to path :write-csv-to [--anonymize] path
══════════════════════════════════════════════════════════════════════ ══════════════════════════════════════════════════════════════════════
Write SQL results to the given file in CSV format Write SQL results to the given file in CSV format
Parameter Parameters
path The path to the file to write --anonymize Anonymize the row contents
path The path to the file to write
See Also See Also
:alt-msg, :append-to, :create-logline-table, :create-search-table, :alt-msg, :append-to, :create-logline-table, :create-search-table,
:echo, :echo, :eval, :export-session-to, :export-session-to, :echo, :echo, :eval, :export-session-to, :export-session-to,
@ -1606,11 +1608,12 @@ For support questions, email:
:write-json-to path :write-json-to [--anonymize] path
══════════════════════════════════════════════════════════════════════ ══════════════════════════════════════════════════════════════════════
Write SQL results to the given file in JSON format Write SQL results to the given file in JSON format
Parameter Parameters
path The path to the file to write --anonymize Anonymize the JSON values
path The path to the file to write
See Also See Also
:alt-msg, :append-to, :create-logline-table, :create-search-table, :alt-msg, :append-to, :create-logline-table, :create-search-table,
:echo, :echo, :eval, :export-session-to, :export-session-to, :echo, :echo, :eval, :export-session-to, :export-session-to,
@ -1626,11 +1629,12 @@ For support questions, email:
:write-jsonlines-to path :write-jsonlines-to [--anonymize] path
══════════════════════════════════════════════════════════════════════ ══════════════════════════════════════════════════════════════════════
Write SQL results to the given file in JSON Lines format Write SQL results to the given file in JSON Lines format
Parameter Parameters
path The path to the file to write --anonymize Anonymize the JSON values
path The path to the file to write
See Also See Also
:alt-msg, :append-to, :create-logline-table, :create-search-table, :alt-msg, :append-to, :create-logline-table, :create-search-table,
:echo, :echo, :eval, :export-session-to, :export-session-to, :echo, :echo, :eval, :export-session-to, :export-session-to,
@ -1646,7 +1650,7 @@ For support questions, email:
:write-raw-to [--view={log,db}] path :write-raw-to [--view={log,db}] [--anonymize] path
══════════════════════════════════════════════════════════════════════ ══════════════════════════════════════════════════════════════════════
In the log view, write the original log file content of the marked In the log view, write the original log file content of the marked
messages to the file. In the DB view, the contents of the cells are messages to the file. In the DB view, the contents of the cells are
@ -1654,6 +1658,7 @@ For support questions, email:
Parameters Parameters
--view={log,db} The view to use as the source of --view={log,db} The view to use as the source of
data data
--anonymize Anonymize the lines
path The path to the file to write path The path to the file to write
See Also See Also
:alt-msg, :append-to, :create-logline-table, :create-search-table, :alt-msg, :append-to, :create-logline-table, :create-search-table,
@ -1671,12 +1676,13 @@ For support questions, email:
:write-screen-to path :write-screen-to [--anonymize] path
══════════════════════════════════════════════════════════════════════ ══════════════════════════════════════════════════════════════════════
Write the displayed text or SQL results to the given file without Write the displayed text or SQL results to the given file without
any formatting any formatting
Parameter Parameters
path The path to the file to write --anonymize Anonymize the lines
path The path to the file to write
See Also See Also
:alt-msg, :append-to, :create-logline-table, :create-search-table, :alt-msg, :append-to, :create-logline-table, :create-search-table,
:echo, :echo, :eval, :export-session-to, :export-session-to, :echo, :echo, :eval, :export-session-to, :export-session-to,
@ -1693,11 +1699,12 @@ For support questions, email:
:write-table-to path :write-table-to [--anonymize] path
══════════════════════════════════════════════════════════════════════ ══════════════════════════════════════════════════════════════════════
Write SQL results to the given file in a tabular format Write SQL results to the given file in a tabular format
Parameter Parameters
path The path to the file to write --anonymize Anonymize the table contents
path The path to the file to write
See Also See Also
:alt-msg, :append-to, :create-logline-table, :create-search-table, :alt-msg, :append-to, :create-logline-table, :create-search-table,
:echo, :echo, :eval, :export-session-to, :export-session-to, :echo, :echo, :eval, :export-session-to, :export-session-to,
@ -1714,11 +1721,12 @@ For support questions, email:
:write-to path :write-to [--anonymize] path
══════════════════════════════════════════════════════════════════════ ══════════════════════════════════════════════════════════════════════
Overwrite the given file with any marked lines in the current view Overwrite the given file with any marked lines in the current view
Parameter Parameters
path The path to the file to write --anonymize Anonymize the lines
path The path to the file to write
See Also See Also
:alt-msg, :append-to, :echo, :echo, :eval, :export-session-to, :alt-msg, :append-to, :echo, :echo, :eval, :export-session-to,
:export-session-to, :pipe-line-to, :pipe-to, :rebuild, :redirect-to, :export-session-to, :pipe-line-to, :pipe-to, :rebuild, :redirect-to,
@ -1733,12 +1741,13 @@ For support questions, email:
:write-view-to path :write-view-to [--anonymize] path
══════════════════════════════════════════════════════════════════════ ══════════════════════════════════════════════════════════════════════
Write the text in the top view to the given file without any Write the text in the top view to the given file without any
formatting formatting
Parameter Parameters
path The path to the file to write --anonymize Anonymize the lines
path The path to the file to write
See Also See Also
:alt-msg, :append-to, :create-logline-table, :create-search-table, :alt-msg, :append-to, :create-logline-table, :create-search-table,
:echo, :echo, :eval, :export-session-to, :export-session-to, :echo, :echo, :eval, :export-session-to, :export-session-to,
@ -1842,6 +1851,26 @@ For support questions, email:
anonymize(value)
══════════════════════════════════════════════════════════════════════
Replace identifying information with random values.
Parameter
value The text to anonymize
See Also
char(), charindex(), decode(), encode(), endswith(), extract(),
group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
strfilter(), substr(), trim(), unicode(), upper(), xpath()
Example
#1 To anonymize an IP address:
;SELECT anonymize('Hello, 192.168.1.2') 
asin(num) asin(num)
══════════════════════════════════════════════════════════════════════ ══════════════════════════════════════════════════════════════════════
Returns the arcsine of a number, in radians Returns the arcsine of a number, in radians
@ -2018,14 +2047,14 @@ For support questions, email:
Parameter Parameter
X The unicode code point values X The unicode code point values
See Also See Also
charindex(), decode(), encode(), endswith(), extract(), group_concat(), anonymize(), charindex(), decode(), encode(), endswith(), extract(),
group_spooky_hash(), gunzip(), gzip(), humanize_duration(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_file_size(), instr(), leftstr(), length(), logfmt2json(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
lower(), ltrim(), padc(), padl(), padr(), printf(), proper(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
regexp_capture(), regexp_capture_into_json(), regexp_match(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_replace(), replace(), replicate(), reverse(), rightstr(), regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rtrim(), sparkline(), spooky_hash(), startswith(), strfilter(), rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
substr(), trim(), unicode(), upper(), xpath() strfilter(), substr(), trim(), unicode(), upper(), xpath()
Example Example
#1 To get a string with the code points 0x48 and 0x49: #1 To get a string with the code points 0x48 and 0x49:
;SELECT char(0x48, 0x49)  ;SELECT char(0x48, 0x49) 
@ -2043,14 +2072,14 @@ For support questions, email:
start The one-based index within the haystack to start The one-based index within the haystack to
start the search start the search
See Also See Also
char(), decode(), encode(), endswith(), extract(), group_concat(), anonymize(), char(), decode(), encode(), endswith(), extract(),
group_spooky_hash(), gunzip(), gzip(), humanize_duration(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_file_size(), instr(), leftstr(), length(), logfmt2json(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
lower(), ltrim(), padc(), padl(), padr(), printf(), proper(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
regexp_capture(), regexp_capture_into_json(), regexp_match(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_replace(), replace(), replicate(), reverse(), rightstr(), regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rtrim(), sparkline(), spooky_hash(), startswith(), strfilter(), rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
substr(), trim(), unicode(), upper(), xpath() strfilter(), substr(), trim(), unicode(), upper(), xpath()
Examples Examples
#1 To search for the string 'abc' within 'abcabc' and starting at position 2: #1 To search for the string 'abc' within 'abcabc' and starting at position 2:
;SELECT charindex('abc', 'abcabc', 2)  ;SELECT charindex('abc', 'abcabc', 2) 
@ -2156,14 +2185,14 @@ For support questions, email:
algorithm One of the following encoding algorithms: algorithm One of the following encoding algorithms:
base64, hex, uri base64, hex, uri
See Also See Also
char(), charindex(), encode(), endswith(), extract(), group_concat(), anonymize(), char(), charindex(), encode(), endswith(), extract(),
group_spooky_hash(), gunzip(), gzip(), humanize_duration(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_file_size(), instr(), leftstr(), length(), logfmt2json(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
lower(), ltrim(), padc(), padl(), padr(), printf(), proper(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
regexp_capture(), regexp_capture_into_json(), regexp_match(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_replace(), replace(), replicate(), reverse(), rightstr(), regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rtrim(), sparkline(), spooky_hash(), startswith(), strfilter(), rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
substr(), trim(), unicode(), upper(), xpath() strfilter(), substr(), trim(), unicode(), upper(), xpath()
Example Example
#1 To decode the URI-encoded string '%63%75%72%6c': #1 To decode the URI-encoded string '%63%75%72%6c':
;SELECT decode('%63%75%72%6c', 'uri')  ;SELECT decode('%63%75%72%6c', 'uri') 
@ -2241,14 +2270,14 @@ For support questions, email:
algorithm One of the following encoding algorithms: algorithm One of the following encoding algorithms:
base64, hex, uri base64, hex, uri
See Also See Also
char(), charindex(), decode(), endswith(), extract(), group_concat(), anonymize(), char(), charindex(), decode(), endswith(), extract(),
group_spooky_hash(), gunzip(), gzip(), humanize_duration(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_file_size(), instr(), leftstr(), length(), logfmt2json(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
lower(), ltrim(), padc(), padl(), padr(), printf(), proper(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
regexp_capture(), regexp_capture_into_json(), regexp_match(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_replace(), replace(), replicate(), reverse(), rightstr(), regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rtrim(), sparkline(), spooky_hash(), startswith(), strfilter(), rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
substr(), trim(), unicode(), upper(), xpath() strfilter(), substr(), trim(), unicode(), upper(), xpath()
Examples Examples
#1 To base64-encode 'Hello, World!': #1 To base64-encode 'Hello, World!':
;SELECT encode('Hello, World!', 'base64')  ;SELECT encode('Hello, World!', 'base64') 
@ -2270,14 +2299,14 @@ For support questions, email:
str The string to test str The string to test
suffix The suffix to check in the string suffix The suffix to check in the string
See Also See Also
char(), charindex(), decode(), encode(), extract(), group_concat(), anonymize(), char(), charindex(), decode(), encode(), extract(),
group_spooky_hash(), gunzip(), gzip(), humanize_duration(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_file_size(), instr(), leftstr(), length(), logfmt2json(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
lower(), ltrim(), padc(), padl(), padr(), printf(), proper(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
regexp_capture(), regexp_capture_into_json(), regexp_match(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_replace(), replace(), replicate(), reverse(), rightstr(), regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rtrim(), sparkline(), spooky_hash(), startswith(), strfilter(), rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
substr(), trim(), unicode(), upper(), xpath() strfilter(), substr(), trim(), unicode(), upper(), xpath()
Examples Examples
#1 To test if the string 'notbad.jpg' ends with '.jpg': #1 To test if the string 'notbad.jpg' ends with '.jpg':
;SELECT endswith('notbad.jpg', '.jpg')  ;SELECT endswith('notbad.jpg', '.jpg') 
@ -2310,14 +2339,14 @@ For support questions, email:
Parameter Parameter
str The string to parse str The string to parse
See Also See Also
char(), charindex(), decode(), encode(), endswith(), group_concat(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_spooky_hash(), gunzip(), gzip(), humanize_duration(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_file_size(), instr(), leftstr(), length(), logfmt2json(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
lower(), ltrim(), padc(), padl(), padr(), printf(), proper(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
regexp_capture(), regexp_capture_into_json(), regexp_match(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_replace(), replace(), replicate(), reverse(), rightstr(), regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rtrim(), sparkline(), spooky_hash(), startswith(), strfilter(), rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
substr(), trim(), unicode(), upper(), xpath() strfilter(), substr(), trim(), unicode(), upper(), xpath()
Examples Examples
#1 To extract key/value pairs from a string: #1 To extract key/value pairs from a string:
;SELECT extract('foo=1 bar=2 name="Rolo Tomassi"')  ;SELECT extract('foo=1 bar=2 name="Rolo Tomassi"') 
@ -2425,8 +2454,8 @@ For support questions, email:
X The value to concatenate. X The value to concatenate.
sep The separator to place between the values. sep The separator to place between the values.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_spooky_hash(), gunzip(), gzip(), humanize_duration(), extract(), group_spooky_hash(), gunzip(), gzip(), humanize_duration(),
humanize_file_size(), instr(), leftstr(), length(), logfmt2json(), humanize_file_size(), instr(), leftstr(), length(), logfmt2json(),
lower(), ltrim(), padc(), padl(), padr(), printf(), proper(), lower(), ltrim(), padc(), padl(), padr(), printf(), proper(),
regexp_capture(), regexp_capture_into_json(), regexp_match(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
@ -2455,8 +2484,8 @@ For support questions, email:
Parameter Parameter
str The string to hash str The string to hash
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), gunzip(), gzip(), humanize_duration(), extract(), group_concat(), gunzip(), gzip(), humanize_duration(),
humanize_file_size(), instr(), leftstr(), length(), logfmt2json(), humanize_file_size(), instr(), leftstr(), length(), logfmt2json(),
lower(), ltrim(), padc(), padl(), padr(), printf(), proper(), lower(), ltrim(), padc(), padl(), padr(), printf(), proper(),
regexp_capture(), regexp_capture_into_json(), regexp_match(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
@ -2475,14 +2504,14 @@ For support questions, email:
Parameter Parameter
b The blob to decompress b The blob to decompress
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gzip(), humanize_duration(), extract(), group_concat(), group_spooky_hash(), gzip(),
humanize_file_size(), instr(), leftstr(), length(), logfmt2json(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
lower(), ltrim(), padc(), padl(), padr(), printf(), proper(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
regexp_capture(), regexp_capture_into_json(), regexp_match(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_replace(), replace(), replicate(), reverse(), rightstr(), regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rtrim(), sparkline(), spooky_hash(), startswith(), strfilter(), rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
substr(), trim(), unicode(), upper(), xpath() strfilter(), substr(), trim(), unicode(), upper(), xpath()
gzip(value, ...) gzip(value, ...)
══════════════════════════════════════════════════════════════════════ ══════════════════════════════════════════════════════════════════════
@ -2490,14 +2519,14 @@ For support questions, email:
Parameter Parameter
value The value to compress value The value to compress
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), humanize_duration(), extract(), group_concat(), group_spooky_hash(), gunzip(),
humanize_file_size(), instr(), leftstr(), length(), logfmt2json(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
lower(), ltrim(), padc(), padl(), padr(), printf(), proper(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
regexp_capture(), regexp_capture_into_json(), regexp_match(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_replace(), replace(), replicate(), reverse(), rightstr(), regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rtrim(), sparkline(), spooky_hash(), startswith(), strfilter(), rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
substr(), trim(), unicode(), upper(), xpath() strfilter(), substr(), trim(), unicode(), upper(), xpath()
hex(X) hex(X)
══════════════════════════════════════════════════════════════════════ ══════════════════════════════════════════════════════════════════════
@ -2518,15 +2547,15 @@ For support questions, email:
Parameter Parameter
secs The duration in seconds secs The duration in seconds
See Also See Also
char(), charindex(), date(), datetime(), decode(), encode(), anonymize(), char(), charindex(), date(), datetime(), decode(),
endswith(), extract(), group_concat(), group_spooky_hash(), gunzip(), encode(), endswith(), extract(), group_concat(), group_spooky_hash(),
gzip(), humanize_file_size(), instr(), julianday(), leftstr(), gunzip(), gzip(), humanize_file_size(), instr(), julianday(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), leftstr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), padr(), printf(), proper(), regexp_capture(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(), regexp_capture_into_json(), regexp_match(), regexp_replace(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(), replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
strfilter(), strftime(), substr(), time(), timediff(), timeslice(), spooky_hash(), startswith(), strfilter(), strftime(), substr(), time(),
trim(), unicode(), upper(), xpath() timediff(), timeslice(), trim(), unicode(), upper(), xpath()
Examples Examples
#1 To format a duration: #1 To format a duration:
;SELECT humanize_duration(15 * 60)  ;SELECT humanize_duration(15 * 60) 
@ -2543,8 +2572,8 @@ For support questions, email:
Parameter Parameter
value The file size to format value The file size to format
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), instr(), leftstr(), length(), logfmt2json(), humanize_duration(), instr(), leftstr(), length(), logfmt2json(),
lower(), ltrim(), padc(), padl(), padr(), printf(), proper(), lower(), ltrim(), padc(), padl(), padr(), printf(), proper(),
regexp_capture(), regexp_capture_into_json(), regexp_match(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
@ -2580,8 +2609,8 @@ For support questions, email:
haystack The string to search within haystack The string to search within
needle The string to look for in the haystack needle The string to look for in the haystack
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), leftstr(), length(), humanize_duration(), humanize_file_size(), leftstr(), length(),
logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), printf(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), printf(),
proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(), proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
@ -2805,8 +2834,8 @@ For support questions, email:
N The number of characters from the left side of the N The number of characters from the left side of the
string to return. string to return.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), length(), humanize_duration(), humanize_file_size(), instr(), length(),
logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), printf(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), printf(),
proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(), proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
@ -2830,8 +2859,8 @@ For support questions, email:
Parameter Parameter
str The string to determine the length of str The string to determine the length of
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), printf(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), printf(),
proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(), proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
@ -2950,8 +2979,8 @@ For support questions, email:
Parameter Parameter
str The logfmt message to parse str The logfmt message to parse
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), lower(), ltrim(), padc(), padl(), padr(), printf(), proper(), length(), lower(), ltrim(), padc(), padl(), padr(), printf(), proper(),
regexp_capture(), regexp_capture_into_json(), regexp_match(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
@ -2971,8 +3000,8 @@ For support questions, email:
Parameter Parameter
str The string to convert. str The string to convert.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), ltrim(), padc(), padl(), padr(), printf(), length(), logfmt2json(), ltrim(), padc(), padl(), padr(), printf(),
proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(), proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
@ -2993,8 +3022,8 @@ For support questions, email:
str The string to trim characters from the left side str The string to trim characters from the left side
chars The characters to trim. Defaults to spaces. chars The characters to trim. Defaults to spaces.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), padc(), padl(), padr(), printf(), length(), logfmt2json(), lower(), padc(), padl(), padr(), printf(),
proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(), proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
@ -3101,8 +3130,8 @@ For support questions, email:
str The string to pad str The string to pad
len The minimum desired length of the output string len The minimum desired length of the output string
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padl(), padr(), printf(), length(), logfmt2json(), lower(), ltrim(), padl(), padr(), printf(),
proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(), proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
@ -3127,8 +3156,8 @@ For support questions, email:
str The string to pad str The string to pad
len The minimum desired length of the output string len The minimum desired length of the output string
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padr(), printf(), length(), logfmt2json(), lower(), ltrim(), padc(), padr(), printf(),
proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(), proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
@ -3153,8 +3182,8 @@ For support questions, email:
str The string to pad str The string to pad
len The minimum desired length of the output string len The minimum desired length of the output string
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), printf(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), printf(),
proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(), proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
@ -3219,8 +3248,8 @@ For support questions, email:
X The argument to substitute at a given position in X The argument to substitute at a given position in
the format. the format.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(), proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
@ -3247,8 +3276,8 @@ For support questions, email:
Parameter Parameter
str The string to capitalize. str The string to capitalize.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), regexp_capture(), regexp_capture_into_json(), regexp_match(), printf(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
@ -3370,8 +3399,8 @@ For support questions, email:
string. string.
content The captured value from the string. content The captured value from the string.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture_into_json(), regexp_match(), printf(), proper(), regexp_capture_into_json(), regexp_match(),
@ -3403,8 +3432,8 @@ For support questions, email:
string. string.
content The captured values from the string. content The captured values from the string.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(), printf(), proper(), regexp_capture(), regexp_match(), regexp_replace(),
@ -3425,8 +3454,8 @@ For support questions, email:
re The regular expression to use re The regular expression to use
str The string to test against the regular expression str The string to test against the regular expression
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
@ -3459,8 +3488,8 @@ For support questions, email:
groups with a backslash followed by the number of the group, groups with a backslash followed by the number of the group,
starting with 1. starting with 1.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
@ -3487,8 +3516,8 @@ For support questions, email:
replacement The string to replace any occurrences of replacement The string to replace any occurrences of
the old string with. the old string with.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
@ -3512,8 +3541,8 @@ For support questions, email:
str The string to replicate. str The string to replicate.
N The number of times to replicate the string. N The number of times to replicate the string.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
@ -3532,8 +3561,8 @@ For support questions, email:
Parameter Parameter
str The string to reverse. str The string to reverse.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
@ -3554,8 +3583,8 @@ For support questions, email:
N The number of characters from the right side of the N The number of characters from the right side of the
string to return. string to return.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
@ -3621,8 +3650,8 @@ For support questions, email:
str The string to trim characters from the right side str The string to trim characters from the right side
chars The characters to trim. Defaults to spaces. chars The characters to trim. Defaults to spaces.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
@ -3675,8 +3704,8 @@ For support questions, email:
non-aggregate version defaults to 100. The aggregate non-aggregate version defaults to 100. The aggregate
version uses the largest value in the inputs. version uses the largest value in the inputs.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
@ -3699,8 +3728,8 @@ For support questions, email:
Parameter Parameter
str The string to hash str The string to hash
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
@ -3780,8 +3809,8 @@ For support questions, email:
str The string to test str The string to test
prefix The prefix to check in the string prefix The prefix to check in the string
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
@ -3806,8 +3835,8 @@ For support questions, email:
source The string to filter source The string to filter
include The characters to include in the result include The characters to include in the result
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
@ -3863,8 +3892,8 @@ For support questions, email:
the value is negative, then the characters before the start the value is negative, then the characters before the start
are returned. are returned.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
@ -4012,8 +4041,8 @@ For support questions, email:
right sides. right sides.
chars The characters to trim. Defaults to spaces. chars The characters to trim. Defaults to spaces.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
@ -4054,8 +4083,8 @@ For support questions, email:
Parameter Parameter
X The string to examine. X The string to examine.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
@ -4082,8 +4111,8 @@ For support questions, email:
Parameter Parameter
str The string to convert. str The string to convert.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),
@ -4111,8 +4140,8 @@ For support questions, email:
node_attr The node's attributes stored in JSON object. node_attr The node's attributes stored in JSON object.
node_text The node's text value. node_text The node's text value.
See Also See Also
char(), charindex(), decode(), encode(), endswith(), extract(), anonymize(), char(), charindex(), decode(), encode(), endswith(),
group_concat(), group_spooky_hash(), gunzip(), gzip(), extract(), group_concat(), group_spooky_hash(), gunzip(), gzip(),
humanize_duration(), humanize_file_size(), instr(), leftstr(), humanize_duration(), humanize_file_size(), instr(), leftstr(),
length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), length(), logfmt2json(), lower(), ltrim(), padc(), padl(), padr(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(), printf(), proper(), regexp_capture(), regexp_capture_into_json(),

@ -0,0 +1,3 @@
10.0.0.1 - - [20/Jul/2009:22:59:26 +0000] "GET /vmw/cgi/aberrant HTTP/1.0" 200 134 "-" "gPXE/0.9.7"
10.0.0.1 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/abject/ablaze/able.gz HTTP/1.0" 404 46210 "-" "gPXE/0.9.7"
10.0.0.1 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/abject/ablaze/aboard.gz HTTP/1.0" 200 78929 "-" "gPXE/0.9.7"

@ -0,0 +1,198 @@
anonymize(bro_id_resp_h)
10.0.0.1
10.0.0.2
10.0.0.2
10.0.0.2
10.0.0.2
10.0.0.2
10.0.0.2
10.0.0.3
10.0.0.4
10.0.0.1
10.0.0.4
10.0.0.4
10.0.0.5
10.0.0.4
10.0.0.4
10.0.0.1
10.0.0.6
10.0.0.4
10.0.0.7
10.0.0.8
10.0.0.8
10.0.0.8
10.0.0.8
10.0.0.8
10.0.0.8
10.0.0.8
10.0.0.8
10.0.0.9
10.0.0.10
10.0.0.5
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.5
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.5
10.0.0.10
10.0.0.6
10.0.0.12
10.0.0.1
10.0.0.1
10.0.0.6
10.0.0.11
10.0.0.11
10.0.0.13
10.0.0.6
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.13
10.0.0.6
10.0.0.6
10.0.0.6
10.0.0.6
10.0.0.6
10.0.0.6
10.0.0.6
10.0.0.6
10.0.0.14
10.0.0.6
10.0.0.14
10.0.0.15
10.0.0.16
10.0.0.6
10.0.0.16
10.0.0.17
10.0.0.5
10.0.0.1
10.0.0.17
10.0.0.15
10.0.0.17
10.0.0.18
10.0.0.18
10.0.0.10
10.0.0.5
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.18
10.0.0.11
10.0.0.11
10.0.0.11
10.0.0.18
10.0.0.18
10.0.0.18
10.0.0.19
10.0.0.18
10.0.0.19
10.0.0.19
10.0.0.19
10.0.0.19
10.0.0.19
10.0.0.19
10.0.0.19
10.0.0.19
10.0.0.20
10.0.0.20
10.0.0.21
10.0.0.18
10.0.0.18
10.0.0.22
10.0.0.6
10.0.0.5
10.0.0.5
10.0.0.5
10.0.0.5
10.0.0.6
10.0.0.23
10.0.0.24
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.24
10.0.0.24
10.0.0.24
10.0.0.24
10.0.0.25
10.0.0.26
10.0.0.27
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.25
10.0.0.26
10.0.0.24
10.0.0.24
10.0.0.27
10.0.0.23
10.0.0.25
10.0.0.26
10.0.0.24
10.0.0.24
10.0.0.27
10.0.0.25
10.0.0.26
10.0.0.24
10.0.0.24
10.0.0.27
10.0.0.28
10.0.0.23
10.0.0.25
10.0.0.24
10.0.0.24
10.0.0.27
10.0.0.26
10.0.0.23
10.0.0.25
10.0.0.26
10.0.0.24
10.0.0.24
10.0.0.27
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.23
10.0.0.27
10.0.0.23
10.0.0.25
10.0.0.24
10.0.0.24
10.0.0.27
10.0.0.26

@ -57,6 +57,14 @@ run_cap_test ${lnav_test} -n -d /tmp/lnav.err \
-c ":write-view-to -" \ -c ":write-view-to -" \
"${test_dir}/logfile_access_log.0" "${test_dir}/logfile_access_log.0"
run_cap_test ${lnav_test} -n -d /tmp/lnav.err \
-c ":write-view-to --anonymize -" \
"${test_dir}/logfile_access_log.0"
run_cap_test ${lnav_test} -n -d /tmp/lnav.err \
-c ":write-view-to --anonymize -" \
"${test_dir}/logfile_pretty.0"
run_cap_test ${lnav_test} -n -d /tmp/lnav.err \ run_cap_test ${lnav_test} -n -d /tmp/lnav.err \
-c ":filter-expr timeslice(:log_time_msecs, 'bad') is not null" \ -c ":filter-expr timeslice(:log_time_msecs, 'bad') is not null" \
"${test_dir}/logfile_multiline.0" "${test_dir}/logfile_multiline.0"

@ -115,3 +115,7 @@ run_cap_test ${lnav_test} -n \
-c ';SELECT log_body, extract(log_body) from vmw_log' \ -c ';SELECT log_body, extract(log_body) from vmw_log' \
-c ':write-json-to -' \ -c ':write-json-to -' \
${test_dir}/logfile_vmw_log.0 ${test_dir}/logfile_vmw_log.0
run_cap_test ${lnav_test} -n \
-c ';SELECT anonymize(bro_id_resp_h) FROM bro_http_log' \
${test_dir}/logfile_bro_http.log.0

@ -0,0 +1,131 @@
/**
* Copyright (c) 2022, Timothy Stack
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Timothy Stack nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest/doctest.h"
#include "text_anonymizer.hh"
TEST_CASE("ipv4")
{
lnav::text_anonymizer ta;
CHECK(ta.next(string_fragment::from_const("127.0.1.1 says hi"))
== "10.0.0.1 says hi");
CHECK(ta.next(string_fragment::from_const("127.0.1.1 says hi"))
== "10.0.0.1 says hi");
CHECK(ta.next(string_fragment::from_const("u'127.0.1.1' says hi"))
== "u'10.0.0.1' says hi");
}
TEST_CASE("ipv6")
{
lnav::text_anonymizer ta;
CHECK(ta.next(
string_fragment::from_const("fe80::1887:2f2d:bc2e:8e41 says hi"))
== "2001:db8::1 says hi");
}
TEST_CASE("url")
{
lnav::text_anonymizer ta;
CHECK(ta.next(string_fragment::from_const("retrieving https://bob:abc@example.com/fooooooo22/192.168.1.33/barrrrr44?abcdef=foobar&ghijkl=123456&bazzer&ip=192.168.1.2#heading-2")) ==
"aback https://meerkat:67c93775f715ab8ab01178caf86713c6@achondroplasia.example.com/abaft22/10.0.0.1/abashed44?aberrant=abhorrent&abiding=123456&abject&ip=10.0.0.2#able-2");
}
TEST_CASE("email")
{
lnav::text_anonymizer ta;
CHECK(ta.next(string_fragment::from_const("hello support@lnav.org"))
== "aback meerkat@achondroplasia.example.com");
}
TEST_CASE("symbol")
{
lnav::text_anonymizer ta;
CHECK(ta.next(string_fragment::from_const(
"state is Constants.DOWNLOAD_STARTED"))
== "aback is Abandoned.ABASHED_ABERRANT");
}
TEST_CASE("date")
{
lnav::text_anonymizer ta;
CHECK(ta.next(string_fragment::from_const("2022-06-02T12:26:22.072Z"))
== "2022-06-02T12:26:22.072Z");
}
TEST_CASE("uuid")
{
lnav::text_anonymizer ta;
CHECK(ta.next(string_fragment::from_const(
"52556d7e-c34d-d7f9-73b6-f52ad939952e"))
== "bc8b6954-c2a4-e7f3-0e18-2fa4035db1c9");
}
TEST_CASE("MAC-address")
{
lnav::text_anonymizer ta;
CHECK(ta.next(string_fragment::from_const("ether f2:09:1a:a2:e3:e2"))
== "aback 00:00:5e:00:53:00");
}
TEST_CASE("hex-dump")
{
lnav::text_anonymizer ta;
CHECK(ta.next(string_fragment::from_const("key f2:09:1a:a2"))
== "key 2d:20:0d:cc");
}
TEST_CASE("cc")
{
lnav::text_anonymizer ta;
CHECK(ta.next(string_fragment::from_const("cc 6011 1111 1111 1117"))
== "cc 1a49 c794 31d9 3eb2");
CHECK(ta.next(string_fragment::from_const("cc 6011111111111117"))
== "cc 1a49c79431d93eb2");
}
TEST_CASE("xml")
{
lnav::text_anonymizer ta;
CHECK(ta.next(string_fragment::from_const("<o:gupdate xmlns:o=\"http://www.google.com/update2/request\" protocol=\"2.0\" version=\"KeystoneDaemon-1.2.0.7709\" ismachine=\"1\" requestid=\"{0DFDBCD1-5E29-4DFC-BD99-31A2397198FE}\">")) ==
"<o:gupdate xmlns:o=\"http://achondroplasia.example.com/aback2/abandoned\" protocol=\"2.0\" version=\"Abashed-1.2.0.7709\" ismachine=\"1\" requestid=\"{1ca0a968-cbe9-e75b-d00b-4859609878ea}\">");
}
Loading…
Cancel
Save