diff --git a/Base/usr/share/man/man1/sort.md b/Base/usr/share/man/man1/sort.md index e38e6c6a6c..cf298bb423 100644 --- a/Base/usr/share/man/man1/sort.md +++ b/Base/usr/share/man/man1/sort.md @@ -19,6 +19,7 @@ Sort each lines of INPUT (or standard input). A quick sort algorithm is used. * `-n`, `--numeric`: Treat the key field as a number * `-t char`, `--sep char`: The separator to split fields by * `-r`, `--reverse`: Sort in reverse order +* `-z`, `--zero-terminated`: Use `\0` as the line delimiter instead of a newline ## Examples diff --git a/Userland/Utilities/sort.cpp b/Userland/Utilities/sort.cpp index 25413ef699..05e2db6e16 100644 --- a/Userland/Utilities/sort.cpp +++ b/Userland/Utilities/sort.cpp @@ -56,11 +56,12 @@ struct Options { bool unique { false }; bool numeric { false }; bool reverse { false }; + bool zero_terminated { false }; StringView separator { "\0", 1 }; Vector files; }; -static ErrorOr load_file(Options options, StringView filename, Vector& lines, HashTable& seen) +static ErrorOr load_file(Options const& options, StringView filename, StringView line_delimiter, Vector& lines, HashTable& seen) { auto file = TRY(Core::InputBufferedFile::create( TRY(Core::File::open_file_or_standard_stream(filename, Core::File::OpenMode::Read)))); @@ -68,8 +69,7 @@ static ErrorOr load_file(Options options, StringView filename, Vectorcan_read_line())) { - DeprecatedString line = TRY(file->read_line(buffer)); - + DeprecatedString line { TRY(file->read_until(buffer, line_delimiter)) }; StringView key = line; if (options.key_field != 0) { auto split = (options.separator[0]) @@ -106,25 +106,27 @@ ErrorOr serenity_main([[maybe_unused]] Main::Arguments arguments) args_parser.add_option(options.numeric, "treat the key field as a number", "numeric", 'n'); args_parser.add_option(options.separator, "The separator to split fields by", "sep", 't', "char"); args_parser.add_option(options.reverse, "Sort in reverse order", "reverse", 'r'); + args_parser.add_option(options.zero_terminated, "Use '\\0' as the line delimiter instead of a newline", "zero-terminated", 'z'); args_parser.add_positional_argument(options.files, "Files to sort", "file", Core::ArgsParser::Required::No); args_parser.parse(arguments); + auto line_delimiter = options.zero_terminated ? "\0"sv : "\n"sv; Vector lines; HashTable seen; if (options.files.size() == 0) { - TRY(load_file(options, "-"sv, lines, seen)); + TRY(load_file(options, "-"sv, line_delimiter, lines, seen)); } else { for (auto& file : options.files) { - TRY(load_file(options, file, lines, seen)); + TRY(load_file(options, file, line_delimiter, lines, seen)); } } quick_sort(lines); - auto print_lines = [](auto const& lines) { + auto print_lines = [line_delimiter](auto const& lines) { for (auto& line : lines) - outln("{}", line.line); + out("{}{}", line.line, line_delimiter); }; if (options.reverse)