mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-25 12:23:09 +00:00
Add string join0
string join0 joins its arguments using NUL byte, which complements string split0. For example it allows piping a variable through sort -z.
This commit is contained in:
parent
b1176323e7
commit
73c747d162
5 changed files with 48 additions and 13 deletions
|
@ -4,6 +4,7 @@
|
||||||
\fish{synopsis}
|
\fish{synopsis}
|
||||||
string escape [(-n | --no-quoted)] [--style=xxx] [STRING...]
|
string escape [(-n | --no-quoted)] [--style=xxx] [STRING...]
|
||||||
string join [(-q | --quiet)] SEP [STRING...]
|
string join [(-q | --quiet)] SEP [STRING...]
|
||||||
|
string join0 [(-q | --quiet)] [STRING...]
|
||||||
string length [(-q | --quiet)] [STRING...]
|
string length [(-q | --quiet)] [STRING...]
|
||||||
string lower [(-q | --quiet)] [STRING...]
|
string lower [(-q | --quiet)] [STRING...]
|
||||||
string match [(-a | --all)] [(-e | --entire)] [(-i | --ignore-case)] [(-r | --regex)]
|
string match [(-a | --all)] [(-e | --entire)] [(-i | --ignore-case)] [(-r | --regex)]
|
||||||
|
@ -51,6 +52,10 @@ The third is `--style=url` which ensures the string can be used as a URL by hex
|
||||||
|
|
||||||
`string join` joins its STRING arguments into a single string separated by SEP, which can be an empty string. Exit status: 0 if at least one join was performed, or 1 otherwise.
|
`string join` joins its STRING arguments into a single string separated by SEP, which can be an empty string. Exit status: 0 if at least one join was performed, or 1 otherwise.
|
||||||
|
|
||||||
|
\subsection string-join0 "join0" subcommand
|
||||||
|
|
||||||
|
`string join` joins its STRING arguments into a single string separated by the zero byte (NUL), and adds a trailing NUL. This is most useful in conjunction with tools that accept NUL-delimited input, such as `sort -z`. Exit status: 0 if at least one join was performed, or 1 otherwise.
|
||||||
|
|
||||||
\subsection string-length "length" subcommand
|
\subsection string-length "length" subcommand
|
||||||
|
|
||||||
`string length` reports the length of each string argument in characters. Exit status: 0 if at least one non-empty STRING was given, or 1 otherwise.
|
`string length` reports the length of each string argument in characters. Exit status: 0 if at least one non-empty STRING was given, or 1 otherwise.
|
||||||
|
@ -248,11 +253,18 @@ foo2
|
||||||
<outp>0xBadC0de</outp>
|
<outp>0xBadC0de</outp>
|
||||||
\endfish
|
\endfish
|
||||||
|
|
||||||
\subsection string-example-split0 Split0 Examples
|
\subsection string-example-split0 NUL Delimited Examples
|
||||||
|
|
||||||
\fish{cli-dark}
|
\fish{cli-dark}
|
||||||
# Count files in a directory, without being confused by newlines.
|
>_ # Count files in a directory, without being confused by newlines.
|
||||||
>_ count (find . -print0 | string split0)
|
>_ count (find . -print0 | string split0)
|
||||||
|
<outp>42</outp>
|
||||||
|
|
||||||
|
>_ # Sort a list of elements which may contain newlines
|
||||||
|
>_ set foo beta alpha\ngamma
|
||||||
|
>_ set foo (string join0 $foo | sort -z | string split0)
|
||||||
|
>_ string escape $foo[1]
|
||||||
|
<outp>alpha\ngamma</outp>
|
||||||
\endfish
|
\endfish
|
||||||
|
|
||||||
\subsection string-example-replace-literal Replace Literal Examples
|
\subsection string-example-replace-literal Replace Literal Examples
|
||||||
|
|
|
@ -542,14 +542,15 @@ static int string_unescape(parser_t &parser, io_streams_t &streams, int argc, wc
|
||||||
DIE("should never reach this statement");
|
DIE("should never reach this statement");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int string_join(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
|
static int string_join_maybe0(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv,
|
||||||
|
bool is_join0) {
|
||||||
options_t opts;
|
options_t opts;
|
||||||
opts.quiet_valid = true;
|
opts.quiet_valid = true;
|
||||||
int optind;
|
int optind;
|
||||||
int retval = parse_opts(&opts, &optind, 1, argc, argv, parser, streams);
|
int retval = parse_opts(&opts, &optind, is_join0 ? 0 : 1, argc, argv, parser, streams);
|
||||||
if (retval != STATUS_CMD_OK) return retval;
|
if (retval != STATUS_CMD_OK) return retval;
|
||||||
|
|
||||||
const wchar_t *sep = opts.arg1;
|
const wcstring sep = is_join0 ? wcstring(1, L'\0') : wcstring(opts.arg1);
|
||||||
int nargs = 0;
|
int nargs = 0;
|
||||||
arg_iterator_t aiter(argv, optind, streams);
|
arg_iterator_t aiter(argv, optind, streams);
|
||||||
while (const wcstring *arg = aiter.nextstr()) {
|
while (const wcstring *arg = aiter.nextstr()) {
|
||||||
|
@ -562,12 +563,20 @@ static int string_join(parser_t &parser, io_streams_t &streams, int argc, wchar_
|
||||||
nargs++;
|
nargs++;
|
||||||
}
|
}
|
||||||
if (nargs > 0 && !opts.quiet) {
|
if (nargs > 0 && !opts.quiet) {
|
||||||
streams.out.push_back(L'\n');
|
streams.out.push_back(is_join0 ? L'\0' : L'\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
return nargs > 1 ? STATUS_CMD_OK : STATUS_CMD_ERROR;
|
return nargs > 1 ? STATUS_CMD_OK : STATUS_CMD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int string_join(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
|
||||||
|
return string_join_maybe0(parser, streams, argc, argv, false /* is_join0 */);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int string_join0(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
|
||||||
|
return string_join_maybe0(parser, streams, argc, argv, true /* is_join0 */);
|
||||||
|
}
|
||||||
|
|
||||||
static int string_length(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
|
static int string_length(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
|
||||||
options_t opts;
|
options_t opts;
|
||||||
opts.quiet_valid = true;
|
opts.quiet_valid = true;
|
||||||
|
@ -1271,13 +1280,12 @@ static const struct string_subcommand {
|
||||||
wchar_t **argv); //!OCLINT(unused param)
|
wchar_t **argv); //!OCLINT(unused param)
|
||||||
}
|
}
|
||||||
|
|
||||||
string_subcommands[] = {{L"escape", &string_escape}, {L"join", &string_join},
|
string_subcommands[] = {
|
||||||
{L"length", &string_length}, {L"match", &string_match},
|
{L"escape", &string_escape}, {L"join", &string_join}, {L"join0", &string_join0},
|
||||||
{L"replace", &string_replace}, {L"split", &string_split},
|
{L"length", &string_length}, {L"match", &string_match}, {L"replace", &string_replace},
|
||||||
{L"split0", &string_split0}, {L"sub", &string_sub},
|
{L"split", &string_split}, {L"split0", &string_split0}, {L"sub", &string_sub},
|
||||||
{L"trim", &string_trim}, {L"lower", &string_lower},
|
{L"trim", &string_trim}, {L"lower", &string_lower}, {L"upper", &string_upper},
|
||||||
{L"upper", &string_upper}, {L"repeat", &string_repeat},
|
{L"repeat", &string_repeat}, {L"unescape", &string_unescape}, {NULL, NULL}};
|
||||||
{L"unescape", &string_unescape}, {NULL, NULL}};
|
|
||||||
|
|
||||||
/// The string builtin, for manipulating strings.
|
/// The string builtin, for manipulating strings.
|
||||||
int builtin_string(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
int builtin_string(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||||
|
|
|
@ -298,5 +298,8 @@ string repeat -l fakearg
|
||||||
####################
|
####################
|
||||||
# string split0
|
# string split0
|
||||||
|
|
||||||
|
####################
|
||||||
|
# string join0
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# string split0 in functions
|
# string split0 in functions
|
||||||
|
|
|
@ -348,6 +348,12 @@ count (echo -ne 'abc\x00def\x00ghi' | string split0)
|
||||||
count (echo -ne 'abc\ndef\x00ghi\x00' | string split0)
|
count (echo -ne 'abc\ndef\x00ghi\x00' | string split0)
|
||||||
count (echo -ne 'abc\ndef\nghi' | string split0)
|
count (echo -ne 'abc\ndef\nghi' | string split0)
|
||||||
|
|
||||||
|
logmsg string join0
|
||||||
|
set tmp beta alpha\ngamma
|
||||||
|
count (string join \n $tmp)
|
||||||
|
count (string join0 $tmp)
|
||||||
|
count (string join0 $tmp | string split0)
|
||||||
|
|
||||||
logmsg string split0 in functions
|
logmsg string split0 in functions
|
||||||
# This function outputs some newline-separated content, and some
|
# This function outputs some newline-separated content, and some
|
||||||
# explicitly separated content.
|
# explicitly separated content.
|
||||||
|
|
|
@ -443,6 +443,12 @@ a\x00g
|
||||||
2
|
2
|
||||||
1
|
1
|
||||||
|
|
||||||
|
####################
|
||||||
|
# string join0
|
||||||
|
3
|
||||||
|
2
|
||||||
|
2
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# string split0 in functions
|
# string split0 in functions
|
||||||
4
|
4
|
||||||
|
|
Loading…
Reference in a new issue