diff --git a/docs/src/manpage.md b/docs/src/manpage.md index acd782c823..53496d9c97 100644 --- a/docs/src/manpage.md +++ b/docs/src/manpage.md @@ -209,28 +209,28 @@ MILLER(1) MILLER(1) asserting_map asserting_nonempty_map asserting_not_array asserting_not_empty asserting_not_map asserting_not_null asserting_null asserting_numeric asserting_present asserting_string atan atan2 atanh bitcount boolean - capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh - count depth dhms2fsec dhms2sec distinct_count erf erfc every exec exp expm1 - flatten float floor fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys - get_values gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt hms2fsec - hms2sec hostname index int invqnorm is_absent is_array is_bool is_boolean - is_empty is_empty_map is_error is_float is_int is_map is_nan is_nonempty_map - is_not_array is_not_empty is_not_map is_not_null is_null is_numeric is_present - is_string joink joinkv joinv json_parse json_stringify kurtosis latin1_to_utf8 - leafcount leftpad length localtime2gmt localtime2nsec localtime2sec log log10 - log1p logifit lstrip madd mapdiff mapexcept mapselect mapsum max maxlen md5 - mean meaneb median mexp min minlen mmul mode msub nsec2gmt nsec2gmtdate - nsec2localdate nsec2localtime null_count os percentile percentiles pow qnorm - reduce regextract regextract_or_else rightpad round roundm rstrip sec2dhms - sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256 - sha512 sin sinh skewness sort sort_collection splita splitax splitkv splitkvx - splitnv splitnvx sqrt ssub stddev strfntime strfntime_local strftime - strftime_local string strip strlen strpntime strpntime_local strptime - strptime_local sub substr substr0 substr1 sum sum2 sum3 sum4 sysntime system - systime systimeint tan tanh tolower toupper truncate typeof unflatten unformat - unformatx upntime uptime urand urand32 urandelement urandint urandrange - utf8_to_latin1 variance version ! != !=~ % & && * ** + - . .* .+ .- ./ / // < - << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~ + capitalize cbrt ceil clean_whitespace collapse_whitespace concat contains cos + cosh count depth dhms2fsec dhms2sec distinct_count erf erfc every exec exp + expm1 flatten float floor fmtifnum fmtnum fold format fsec2dhms fsec2hms + get_keys get_values gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt + hms2fsec hms2sec hostname index int invqnorm is_absent is_array is_bool + is_boolean is_empty is_empty_map is_error is_float is_int is_map is_nan + is_nonempty_map is_not_array is_not_empty is_not_map is_not_null is_null + is_numeric is_present is_string joink joinkv joinv json_parse json_stringify + kurtosis latin1_to_utf8 leafcount leftpad length localtime2gmt localtime2nsec + localtime2sec log log10 log1p logifit lstrip madd mapdiff mapexcept mapselect + mapsum max maxlen md5 mean meaneb median mexp min minlen mmul mode msub + nsec2gmt nsec2gmtdate nsec2localdate nsec2localtime null_count os percentile + percentiles pow qnorm reduce regextract regextract_or_else rightpad round + roundm rstrip sec2dhms sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime + select sgn sha1 sha256 sha512 sin sinh skewness sort sort_collection splita + splitax splitkv splitkvx splitnv splitnvx sqrt ssub stddev strfntime + strfntime_local strftime strftime_local string strip strlen strpntime + strpntime_local strptime strptime_local sub substr substr0 substr1 sum sum2 + sum3 sum4 sysntime system systime systimeint tan tanh tolower toupper truncate + typeof unflatten unformat unformatx upntime uptime urand urand32 urandelement + urandint urandrange utf8_to_latin1 variance version ! != !=~ % & && * ** + - . + .* .+ .- ./ / // < << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~ 1mCOMMENTS-IN-DATA FLAGS0m Miller lets you put comments in your data, such as @@ -2311,6 +2311,14 @@ MILLER(1) MILLER(1) concat([1,2],3) is [1,2,3] concat([1,2],[3]) is [1,2,3] + 1mcontains0m + (class=string #args=2) Returns true if the first argument contains the second as a substring. This is like saying `index(arg1, arg2) >= 0`but with less keystroking. + Examples: + contains("abcde", "e") gives true + contains("abcde", "x") gives false + contains(12345, 34) gives true + contains("fort", "") gives true + 1mcos0m (class=math #args=1) Trigonometric cosine. @@ -2461,7 +2469,7 @@ MILLER(1) MILLER(1) (class=string #args=2) Returns the index (1-based) of the second argument within the first. Returns -1 if the second argument isn't a substring of the first. Stringifies non-string inputs. Uses UTF-8 encoding to count characters, not bytes. Examples: index("abcde", "e") gives 5 - index("abcde", "x") gives 01 + index("abcde", "x") gives -1 index(12345, 34) gives 3 index("fort", "t") gives 5 @@ -3634,5 +3642,5 @@ MILLER(1) MILLER(1) - 2023-08-27 MILLER(1) + 2023-08-28 MILLER(1) diff --git a/docs/src/manpage.txt b/docs/src/manpage.txt index e2ed9df203..0141cac606 100644 --- a/docs/src/manpage.txt +++ b/docs/src/manpage.txt @@ -188,28 +188,28 @@ MILLER(1) MILLER(1) asserting_map asserting_nonempty_map asserting_not_array asserting_not_empty asserting_not_map asserting_not_null asserting_null asserting_numeric asserting_present asserting_string atan atan2 atanh bitcount boolean - capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh - count depth dhms2fsec dhms2sec distinct_count erf erfc every exec exp expm1 - flatten float floor fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys - get_values gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt hms2fsec - hms2sec hostname index int invqnorm is_absent is_array is_bool is_boolean - is_empty is_empty_map is_error is_float is_int is_map is_nan is_nonempty_map - is_not_array is_not_empty is_not_map is_not_null is_null is_numeric is_present - is_string joink joinkv joinv json_parse json_stringify kurtosis latin1_to_utf8 - leafcount leftpad length localtime2gmt localtime2nsec localtime2sec log log10 - log1p logifit lstrip madd mapdiff mapexcept mapselect mapsum max maxlen md5 - mean meaneb median mexp min minlen mmul mode msub nsec2gmt nsec2gmtdate - nsec2localdate nsec2localtime null_count os percentile percentiles pow qnorm - reduce regextract regextract_or_else rightpad round roundm rstrip sec2dhms - sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256 - sha512 sin sinh skewness sort sort_collection splita splitax splitkv splitkvx - splitnv splitnvx sqrt ssub stddev strfntime strfntime_local strftime - strftime_local string strip strlen strpntime strpntime_local strptime - strptime_local sub substr substr0 substr1 sum sum2 sum3 sum4 sysntime system - systime systimeint tan tanh tolower toupper truncate typeof unflatten unformat - unformatx upntime uptime urand urand32 urandelement urandint urandrange - utf8_to_latin1 variance version ! != !=~ % & && * ** + - . .* .+ .- ./ / // < - << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~ + capitalize cbrt ceil clean_whitespace collapse_whitespace concat contains cos + cosh count depth dhms2fsec dhms2sec distinct_count erf erfc every exec exp + expm1 flatten float floor fmtifnum fmtnum fold format fsec2dhms fsec2hms + get_keys get_values gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt + hms2fsec hms2sec hostname index int invqnorm is_absent is_array is_bool + is_boolean is_empty is_empty_map is_error is_float is_int is_map is_nan + is_nonempty_map is_not_array is_not_empty is_not_map is_not_null is_null + is_numeric is_present is_string joink joinkv joinv json_parse json_stringify + kurtosis latin1_to_utf8 leafcount leftpad length localtime2gmt localtime2nsec + localtime2sec log log10 log1p logifit lstrip madd mapdiff mapexcept mapselect + mapsum max maxlen md5 mean meaneb median mexp min minlen mmul mode msub + nsec2gmt nsec2gmtdate nsec2localdate nsec2localtime null_count os percentile + percentiles pow qnorm reduce regextract regextract_or_else rightpad round + roundm rstrip sec2dhms sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime + select sgn sha1 sha256 sha512 sin sinh skewness sort sort_collection splita + splitax splitkv splitkvx splitnv splitnvx sqrt ssub stddev strfntime + strfntime_local strftime strftime_local string strip strlen strpntime + strpntime_local strptime strptime_local sub substr substr0 substr1 sum sum2 + sum3 sum4 sysntime system systime systimeint tan tanh tolower toupper truncate + typeof unflatten unformat unformatx upntime uptime urand urand32 urandelement + urandint urandrange utf8_to_latin1 variance version ! != !=~ % & && * ** + - . + .* .+ .- ./ / // < << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~ 1mCOMMENTS-IN-DATA FLAGS0m Miller lets you put comments in your data, such as @@ -2290,6 +2290,14 @@ MILLER(1) MILLER(1) concat([1,2],3) is [1,2,3] concat([1,2],[3]) is [1,2,3] + 1mcontains0m + (class=string #args=2) Returns true if the first argument contains the second as a substring. This is like saying `index(arg1, arg2) >= 0`but with less keystroking. + Examples: + contains("abcde", "e") gives true + contains("abcde", "x") gives false + contains(12345, 34) gives true + contains("fort", "") gives true + 1mcos0m (class=math #args=1) Trigonometric cosine. @@ -2440,7 +2448,7 @@ MILLER(1) MILLER(1) (class=string #args=2) Returns the index (1-based) of the second argument within the first. Returns -1 if the second argument isn't a substring of the first. Stringifies non-string inputs. Uses UTF-8 encoding to count characters, not bytes. Examples: index("abcde", "e") gives 5 - index("abcde", "x") gives 01 + index("abcde", "x") gives -1 index(12345, 34) gives 3 index("fort", "t") gives 5 @@ -3613,4 +3621,4 @@ MILLER(1) MILLER(1) - 2023-08-27 MILLER(1) + 2023-08-28 MILLER(1) diff --git a/docs/src/reference-dsl-builtin-functions.md b/docs/src/reference-dsl-builtin-functions.md index 135d27f14f..3655493c20 100644 --- a/docs/src/reference-dsl-builtin-functions.md +++ b/docs/src/reference-dsl-builtin-functions.md @@ -75,7 +75,7 @@ is 2. Unary operators such as `!` and `~` show argument-count of 1; the ternary * [**Higher-order-functions functions**](#higher-order-functions-functions): [any](#any), [apply](#apply), [every](#every), [fold](#fold), [reduce](#reduce), [select](#select), [sort](#sort). * [**Math functions**](#math-functions): [abs](#abs), [acos](#acos), [acosh](#acosh), [asin](#asin), [asinh](#asinh), [atan](#atan), [atan2](#atan2), [atanh](#atanh), [cbrt](#cbrt), [ceil](#ceil), [cos](#cos), [cosh](#cosh), [erf](#erf), [erfc](#erfc), [exp](#exp), [expm1](#expm1), [floor](#floor), [invqnorm](#invqnorm), [log](#log), [log10](#log10), [log1p](#log1p), [logifit](#logifit), [max](#max), [min](#min), [qnorm](#qnorm), [round](#round), [roundm](#roundm), [sgn](#sgn), [sin](#sin), [sinh](#sinh), [sqrt](#sqrt), [tan](#tan), [tanh](#tanh), [urand](#urand), [urand32](#urand32), [urandelement](#urandelement), [urandint](#urandint), [urandrange](#urandrange). * [**Stats functions**](#stats-functions): [antimode](#antimode), [count](#count), [distinct_count](#distinct_count), [kurtosis](#kurtosis), [maxlen](#maxlen), [mean](#mean), [meaneb](#meaneb), [median](#median), [minlen](#minlen), [mode](#mode), [null_count](#null_count), [percentile](#percentile), [percentiles](#percentiles), [skewness](#skewness), [sort_collection](#sort_collection), [stddev](#stddev), [sum](#sum), [sum2](#sum2), [sum3](#sum3), [sum4](#sum4), [variance](#variance). -* [**String functions**](#string-functions): [capitalize](#capitalize), [clean_whitespace](#clean_whitespace), [collapse_whitespace](#collapse_whitespace), [format](#format), [gssub](#gssub), [gsub](#gsub), [index](#index), [latin1_to_utf8](#latin1_to_utf8), [leftpad](#leftpad), [lstrip](#lstrip), [regextract](#regextract), [regextract_or_else](#regextract_or_else), [rightpad](#rightpad), [rstrip](#rstrip), [ssub](#ssub), [strip](#strip), [strlen](#strlen), [sub](#sub), [substr](#substr), [substr0](#substr0), [substr1](#substr1), [tolower](#tolower), [toupper](#toupper), [truncate](#truncate), [unformat](#unformat), [unformatx](#unformatx), [utf8_to_latin1](#utf8_to_latin1), [\.](#dot). +* [**String functions**](#string-functions): [capitalize](#capitalize), [clean_whitespace](#clean_whitespace), [collapse_whitespace](#collapse_whitespace), [contains](#contains), [format](#format), [gssub](#gssub), [gsub](#gsub), [index](#index), [latin1_to_utf8](#latin1_to_utf8), [leftpad](#leftpad), [lstrip](#lstrip), [regextract](#regextract), [regextract_or_else](#regextract_or_else), [rightpad](#rightpad), [rstrip](#rstrip), [ssub](#ssub), [strip](#strip), [strlen](#strlen), [sub](#sub), [substr](#substr), [substr0](#substr0), [substr1](#substr1), [tolower](#tolower), [toupper](#toupper), [truncate](#truncate), [unformat](#unformat), [unformatx](#unformatx), [utf8_to_latin1](#utf8_to_latin1), [\.](#dot). * [**System functions**](#system-functions): [exec](#exec), [hostname](#hostname), [os](#os), [system](#system), [version](#version). * [**Time functions**](#time-functions): [dhms2fsec](#dhms2fsec), [dhms2sec](#dhms2sec), [fsec2dhms](#fsec2dhms), [fsec2hms](#fsec2hms), [gmt2localtime](#gmt2localtime), [gmt2nsec](#gmt2nsec), [gmt2sec](#gmt2sec), [hms2fsec](#hms2fsec), [hms2sec](#hms2sec), [localtime2gmt](#localtime2gmt), [localtime2nsec](#localtime2nsec), [localtime2sec](#localtime2sec), [nsec2gmt](#nsec2gmt), [nsec2gmtdate](#nsec2gmtdate), [nsec2localdate](#nsec2localdate), [nsec2localtime](#nsec2localtime), [sec2dhms](#sec2dhms), [sec2gmt](#sec2gmt), [sec2gmtdate](#sec2gmtdate), [sec2hms](#sec2hms), [sec2localdate](#sec2localdate), [sec2localtime](#sec2localtime), [strfntime](#strfntime), [strfntime_local](#strfntime_local), [strftime](#strftime), [strftime_local](#strftime_local), [strpntime](#strpntime), [strpntime_local](#strpntime_local), [strptime](#strptime), [strptime_local](#strptime_local), [sysntime](#sysntime), [systime](#systime), [systimeint](#systimeint), [upntime](#upntime), [uptime](#uptime). * [**Typing functions**](#typing-functions): [asserting_absent](#asserting_absent), [asserting_array](#asserting_array), [asserting_bool](#asserting_bool), [asserting_boolean](#asserting_boolean), [asserting_empty](#asserting_empty), [asserting_empty_map](#asserting_empty_map), [asserting_error](#asserting_error), [asserting_float](#asserting_float), [asserting_int](#asserting_int), [asserting_map](#asserting_map), [asserting_nonempty_map](#asserting_nonempty_map), [asserting_not_array](#asserting_not_array), [asserting_not_empty](#asserting_not_empty), [asserting_not_map](#asserting_not_map), [asserting_not_null](#asserting_not_null), [asserting_null](#asserting_null), [asserting_numeric](#asserting_numeric), [asserting_present](#asserting_present), [asserting_string](#asserting_string), [is_absent](#is_absent), [is_array](#is_array), [is_bool](#is_bool), [is_boolean](#is_boolean), [is_empty](#is_empty), [is_empty_map](#is_empty_map), [is_error](#is_error), [is_float](#is_float), [is_int](#is_int), [is_map](#is_map), [is_nan](#is_nan), [is_nonempty_map](#is_nonempty_map), [is_not_array](#is_not_array), [is_not_empty](#is_not_empty), [is_not_map](#is_not_map), [is_not_null](#is_not_null), [is_null](#is_null), [is_numeric](#is_numeric), [is_present](#is_present), [is_string](#is_string), [typeof](#typeof). @@ -1219,6 +1219,17 @@ collapse_whitespace (class=string #args=1) Strip repeated whitespace from strin +### contains +
+contains (class=string #args=2) Returns true if the first argument contains the second as a substring. This is like saying `index(arg1, arg2) >= 0`but with less keystroking. +Examples: +contains("abcde", "e") gives true +contains("abcde", "x") gives false +contains(12345, 34) gives true +contains("forêt", "ê") gives true ++ + ### format
format (class=string #args=variadic) Using first argument as format string, interpolate remaining arguments in place of each "{}" in the format string. Too-few arguments are treated as the empty string; too-many arguments are discarded. @@ -1254,7 +1265,7 @@ gsub("prefix4529:suffix8567", "(....ix)([0-9]+)", "[\1 : \2]") gives "[prefix : index (class=string #args=2) Returns the index (1-based) of the second argument within the first. Returns -1 if the second argument isn't a substring of the first. Stringifies non-string inputs. Uses UTF-8 encoding to count characters, not bytes. Examples: index("abcde", "e") gives 5 -index("abcde", "x") gives 01 +index("abcde", "x") gives -1 index(12345, 34) gives 3 index("forêt", "t") gives 5diff --git a/internal/pkg/bifs/strings.go b/internal/pkg/bifs/strings.go index 4cdcdce935..6e1c76511a 100644 --- a/internal/pkg/bifs/strings.go +++ b/internal/pkg/bifs/strings.go @@ -149,6 +149,20 @@ func BIF_index(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { return mlrval.FromInt(lib.UTF8Strlen(sinput1[:iindex]) + 1) } +// ================================================================ +// contains(string, substring) returns true if string contains substring, else false. + +func BIF_contains(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { + if input1.IsAbsent() { + return mlrval.ABSENT + } + if input1.IsError() { + return mlrval.ERROR + } + + return mlrval.FromBool(strings.Contains(input1.String(), input2.String())) +} + // ================================================================ func BIF_truncate(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { if input1.IsErrorOrAbsent() { diff --git a/internal/pkg/dsl/cst/builtin_function_manager.go b/internal/pkg/dsl/cst/builtin_function_manager.go index 8887c786ea..6d4dc62332 100644 --- a/internal/pkg/dsl/cst/builtin_function_manager.go +++ b/internal/pkg/dsl/cst/builtin_function_manager.go @@ -546,11 +546,23 @@ Arrays are new in Miller 6; the substr function is older.`, binaryFunc: bifs.BIF_index, examples: []string{ `index("abcde", "e") gives 5`, - `index("abcde", "x") gives 01`, + `index("abcde", "x") gives -1`, `index(12345, 34) gives 3`, `index("forêt", "t") gives 5`, }, }, + { + name: "contains", + class: FUNC_CLASS_STRING, + help: `Returns true if the first argument contains the second as a substring. This is like saying ` + "`index(arg1, arg2) >= 0`" + `but with less keystroking.`, + binaryFunc: bifs.BIF_contains, + examples: []string{ + `contains("abcde", "e") gives true`, + `contains("abcde", "x") gives false`, + `contains(12345, 34) gives true`, + `contains("forêt", "ê") gives true`, + }, + }, { name: "tolower", diff --git a/man/manpage.txt b/man/manpage.txt index e2ed9df203..0141cac606 100644 --- a/man/manpage.txt +++ b/man/manpage.txt @@ -188,28 +188,28 @@ MILLER(1) MILLER(1) asserting_map asserting_nonempty_map asserting_not_array asserting_not_empty asserting_not_map asserting_not_null asserting_null asserting_numeric asserting_present asserting_string atan atan2 atanh bitcount boolean - capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh - count depth dhms2fsec dhms2sec distinct_count erf erfc every exec exp expm1 - flatten float floor fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys - get_values gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt hms2fsec - hms2sec hostname index int invqnorm is_absent is_array is_bool is_boolean - is_empty is_empty_map is_error is_float is_int is_map is_nan is_nonempty_map - is_not_array is_not_empty is_not_map is_not_null is_null is_numeric is_present - is_string joink joinkv joinv json_parse json_stringify kurtosis latin1_to_utf8 - leafcount leftpad length localtime2gmt localtime2nsec localtime2sec log log10 - log1p logifit lstrip madd mapdiff mapexcept mapselect mapsum max maxlen md5 - mean meaneb median mexp min minlen mmul mode msub nsec2gmt nsec2gmtdate - nsec2localdate nsec2localtime null_count os percentile percentiles pow qnorm - reduce regextract regextract_or_else rightpad round roundm rstrip sec2dhms - sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256 - sha512 sin sinh skewness sort sort_collection splita splitax splitkv splitkvx - splitnv splitnvx sqrt ssub stddev strfntime strfntime_local strftime - strftime_local string strip strlen strpntime strpntime_local strptime - strptime_local sub substr substr0 substr1 sum sum2 sum3 sum4 sysntime system - systime systimeint tan tanh tolower toupper truncate typeof unflatten unformat - unformatx upntime uptime urand urand32 urandelement urandint urandrange - utf8_to_latin1 variance version ! != !=~ % & && * ** + - . .* .+ .- ./ / // < - << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~ + capitalize cbrt ceil clean_whitespace collapse_whitespace concat contains cos + cosh count depth dhms2fsec dhms2sec distinct_count erf erfc every exec exp + expm1 flatten float floor fmtifnum fmtnum fold format fsec2dhms fsec2hms + get_keys get_values gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt + hms2fsec hms2sec hostname index int invqnorm is_absent is_array is_bool + is_boolean is_empty is_empty_map is_error is_float is_int is_map is_nan + is_nonempty_map is_not_array is_not_empty is_not_map is_not_null is_null + is_numeric is_present is_string joink joinkv joinv json_parse json_stringify + kurtosis latin1_to_utf8 leafcount leftpad length localtime2gmt localtime2nsec + localtime2sec log log10 log1p logifit lstrip madd mapdiff mapexcept mapselect + mapsum max maxlen md5 mean meaneb median mexp min minlen mmul mode msub + nsec2gmt nsec2gmtdate nsec2localdate nsec2localtime null_count os percentile + percentiles pow qnorm reduce regextract regextract_or_else rightpad round + roundm rstrip sec2dhms sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime + select sgn sha1 sha256 sha512 sin sinh skewness sort sort_collection splita + splitax splitkv splitkvx splitnv splitnvx sqrt ssub stddev strfntime + strfntime_local strftime strftime_local string strip strlen strpntime + strpntime_local strptime strptime_local sub substr substr0 substr1 sum sum2 + sum3 sum4 sysntime system systime systimeint tan tanh tolower toupper truncate + typeof unflatten unformat unformatx upntime uptime urand urand32 urandelement + urandint urandrange utf8_to_latin1 variance version ! != !=~ % & && * ** + - . + .* .+ .- ./ / // < << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~ 1mCOMMENTS-IN-DATA FLAGS0m Miller lets you put comments in your data, such as @@ -2290,6 +2290,14 @@ MILLER(1) MILLER(1) concat([1,2],3) is [1,2,3] concat([1,2],[3]) is [1,2,3] + 1mcontains0m + (class=string #args=2) Returns true if the first argument contains the second as a substring. This is like saying `index(arg1, arg2) >= 0`but with less keystroking. + Examples: + contains("abcde", "e") gives true + contains("abcde", "x") gives false + contains(12345, 34) gives true + contains("fort", "") gives true + 1mcos0m (class=math #args=1) Trigonometric cosine. @@ -2440,7 +2448,7 @@ MILLER(1) MILLER(1) (class=string #args=2) Returns the index (1-based) of the second argument within the first. Returns -1 if the second argument isn't a substring of the first. Stringifies non-string inputs. Uses UTF-8 encoding to count characters, not bytes. Examples: index("abcde", "e") gives 5 - index("abcde", "x") gives 01 + index("abcde", "x") gives -1 index(12345, 34) gives 3 index("fort", "t") gives 5 @@ -3613,4 +3621,4 @@ MILLER(1) MILLER(1) - 2023-08-27 MILLER(1) + 2023-08-28 MILLER(1) diff --git a/man/mlr.1 b/man/mlr.1 index 352c6f0c6a..e0f0965b69 100644 --- a/man/mlr.1 +++ b/man/mlr.1 @@ -2,12 +2,12 @@ .\" Title: mlr .\" Author: [see the "AUTHOR" section] .\" Generator: ./mkman.rb -.\" Date: 2023-08-27 +.\" Date: 2023-08-28 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "MILLER" "1" "2023-08-27" "\ \&" "\ \&" +.TH "MILLER" "1" "2023-08-28" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * Portability definitions .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -235,28 +235,28 @@ asserting_empty_map asserting_error asserting_float asserting_int asserting_map asserting_nonempty_map asserting_not_array asserting_not_empty asserting_not_map asserting_not_null asserting_null asserting_numeric asserting_present asserting_string atan atan2 atanh bitcount boolean -capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh -count depth dhms2fsec dhms2sec distinct_count erf erfc every exec exp expm1 -flatten float floor fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys -get_values gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt hms2fsec -hms2sec hostname index int invqnorm is_absent is_array is_bool is_boolean -is_empty is_empty_map is_error is_float is_int is_map is_nan is_nonempty_map -is_not_array is_not_empty is_not_map is_not_null is_null is_numeric is_present -is_string joink joinkv joinv json_parse json_stringify kurtosis latin1_to_utf8 -leafcount leftpad length localtime2gmt localtime2nsec localtime2sec log log10 -log1p logifit lstrip madd mapdiff mapexcept mapselect mapsum max maxlen md5 -mean meaneb median mexp min minlen mmul mode msub nsec2gmt nsec2gmtdate -nsec2localdate nsec2localtime null_count os percentile percentiles pow qnorm -reduce regextract regextract_or_else rightpad round roundm rstrip sec2dhms -sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256 -sha512 sin sinh skewness sort sort_collection splita splitax splitkv splitkvx -splitnv splitnvx sqrt ssub stddev strfntime strfntime_local strftime -strftime_local string strip strlen strpntime strpntime_local strptime -strptime_local sub substr substr0 substr1 sum sum2 sum3 sum4 sysntime system -systime systimeint tan tanh tolower toupper truncate typeof unflatten unformat -unformatx upntime uptime urand urand32 urandelement urandint urandrange -utf8_to_latin1 variance version ! != !=~ % & && * ** + - . .* .+ .- ./ / // < -<< <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~ +capitalize cbrt ceil clean_whitespace collapse_whitespace concat contains cos +cosh count depth dhms2fsec dhms2sec distinct_count erf erfc every exec exp +expm1 flatten float floor fmtifnum fmtnum fold format fsec2dhms fsec2hms +get_keys get_values gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt +hms2fsec hms2sec hostname index int invqnorm is_absent is_array is_bool +is_boolean is_empty is_empty_map is_error is_float is_int is_map is_nan +is_nonempty_map is_not_array is_not_empty is_not_map is_not_null is_null +is_numeric is_present is_string joink joinkv joinv json_parse json_stringify +kurtosis latin1_to_utf8 leafcount leftpad length localtime2gmt localtime2nsec +localtime2sec log log10 log1p logifit lstrip madd mapdiff mapexcept mapselect +mapsum max maxlen md5 mean meaneb median mexp min minlen mmul mode msub +nsec2gmt nsec2gmtdate nsec2localdate nsec2localtime null_count os percentile +percentiles pow qnorm reduce regextract regextract_or_else rightpad round +roundm rstrip sec2dhms sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime +select sgn sha1 sha256 sha512 sin sinh skewness sort sort_collection splita +splitax splitkv splitkvx splitnv splitnvx sqrt ssub stddev strfntime +strfntime_local strftime strftime_local string strip strlen strpntime +strpntime_local strptime strptime_local sub substr substr0 substr1 sum sum2 +sum3 sum4 sysntime system systime systimeint tan tanh tolower toupper truncate +typeof unflatten unformat unformatx upntime uptime urand urand32 urandelement +urandint urandrange utf8_to_latin1 variance version ! != !=~ % & && * ** + - . +\&.* .+ .- ./ / // < << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~ .fi .if n \{\ .RE @@ -3113,6 +3113,20 @@ concat([1,2],[3]) is [1,2,3] .fi .if n \{\ .RE +.SS "contains" +.if n \{\ +.RS 0 +.\} +.nf + (class=string #args=2) Returns true if the first argument contains the second as a substring. This is like saying `index(arg1, arg2) >= 0`but with less keystroking. +Examples: +contains("abcde", "e") gives true +contains("abcde", "x") gives false +contains(12345, 34) gives true +contains("forêt", "ê") gives true +.fi +.if n \{\ +.RE .SS "cos" .if n \{\ .RS 0 @@ -3471,7 +3485,7 @@ gsub("prefix4529:suffix8567", "(....ix)([0-9]+)", "[\e1 : \e2]") gives "[prefix (class=string #args=2) Returns the index (1-based) of the second argument within the first. Returns -1 if the second argument isn't a substring of the first. Stringifies non-string inputs. Uses UTF-8 encoding to count characters, not bytes. Examples: index("abcde", "e") gives 5 -index("abcde", "x") gives 01 +index("abcde", "x") gives -1 index(12345, 34) gives 3 index("forêt", "t") gives 5 .fi diff --git a/test/cases/dsl-contains/0001/cmd b/test/cases/dsl-contains/0001/cmd new file mode 100644 index 0000000000..df47a8b50e --- /dev/null +++ b/test/cases/dsl-contains/0001/cmd @@ -0,0 +1 @@ +mlr -n put -q -f ${CASEDIR}/mlr diff --git a/test/cases/dsl-contains/0001/experr b/test/cases/dsl-contains/0001/experr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/cases/dsl-contains/0001/expout b/test/cases/dsl-contains/0001/expout new file mode 100644 index 0000000000..8ded02ad76 --- /dev/null +++ b/test/cases/dsl-contains/0001/expout @@ -0,0 +1,8 @@ +abc abc true +abc true + true + abc false +abcde abc true +123 3 true +123 34 false +123 23 true diff --git a/test/cases/dsl-contains/0001/mlr b/test/cases/dsl-contains/0001/mlr new file mode 100644 index 0000000000..ea83c5320c --- /dev/null +++ b/test/cases/dsl-contains/0001/mlr @@ -0,0 +1,14 @@ +end { + for (e in [ + ["abc", "abc"], + ["abc", ""], + ["", ""], + ["", "abc"], + ["abcde", "abc"], + ["123", 3], + [123, 34], + [123, 23], + ]) { + print e[1], e[2], contains(e[1], e[2]) + } +}