mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
Merge pull request #8108 from sylvestre/l10n-uniq
l10n: port uniq to translation + add french
This commit is contained in:
commit
8db1b6ed75
3 changed files with 124 additions and 37 deletions
|
@ -5,3 +5,39 @@ uniq-after-help = Filter adjacent matching lines from INPUT (or standard input),
|
|||
|
||||
Note: uniq does not detect repeated lines unless they are adjacent.
|
||||
You may want to sort the input first, or use sort -u without uniq.
|
||||
|
||||
# Help messages
|
||||
uniq-help-all-repeated = print all duplicate lines. Delimiting is done with blank lines. [default: none]
|
||||
uniq-help-group = show all items, separating groups with an empty line. [default: separate]
|
||||
uniq-help-check-chars = compare no more than N characters in lines
|
||||
uniq-help-count = prefix lines by the number of occurrences
|
||||
uniq-help-ignore-case = ignore differences in case when comparing
|
||||
uniq-help-repeated = only print duplicate lines
|
||||
uniq-help-skip-chars = avoid comparing the first N characters
|
||||
uniq-help-skip-fields = avoid comparing the first N fields
|
||||
uniq-help-unique = only print unique lines
|
||||
uniq-help-zero-terminated = end lines with 0 byte, not newline
|
||||
|
||||
# Error messages
|
||||
uniq-error-write-line-terminator = Could not write line terminator
|
||||
uniq-error-write-error = write error
|
||||
uniq-error-invalid-argument = Invalid argument for { $opt_name }: { $arg }
|
||||
uniq-error-try-help = Try 'uniq --help' for more information.
|
||||
uniq-error-group-mutually-exclusive = --group is mutually exclusive with -c/-d/-D/-u
|
||||
uniq-error-group-badoption = invalid argument 'badoption' for '--group'
|
||||
Valid arguments are:
|
||||
- 'prepend'
|
||||
- 'append'
|
||||
- 'separate'
|
||||
- 'both'
|
||||
|
||||
uniq-error-all-repeated-badoption = invalid argument 'badoption' for '--all-repeated'
|
||||
Valid arguments are:
|
||||
- 'none'
|
||||
- 'prepend'
|
||||
- 'separate'
|
||||
|
||||
uniq-error-counts-and-repeated-meaningless = printing all duplicated lines and repeat counts is meaningless
|
||||
Try 'uniq --help' for more information.
|
||||
|
||||
uniq-error-could-not-open = Could not open { $path }
|
||||
|
|
41
src/uu/uniq/locales/fr-FR.ftl
Normal file
41
src/uu/uniq/locales/fr-FR.ftl
Normal file
|
@ -0,0 +1,41 @@
|
|||
uniq-about = Signaler ou omettre les lignes répétées.
|
||||
uniq-usage = uniq [OPTION]... [ENTRÉE [SORTIE]]
|
||||
uniq-after-help = Filtrer les lignes adjacentes correspondantes de ENTRÉE (ou l'entrée standard),
|
||||
en écrivant vers SORTIE (ou la sortie standard).
|
||||
Note : uniq ne détecte les lignes répétées que si elles sont adjacentes.
|
||||
Vous pourriez vouloir trier l'entrée d'abord, ou utiliser sort -u sans uniq.
|
||||
|
||||
# Messages d'aide
|
||||
uniq-help-all-repeated = afficher toutes les lignes dupliquées. La délimitation se fait avec des lignes vides. [défaut : none]
|
||||
uniq-help-group = afficher tous les éléments, en séparant les groupes avec une ligne vide. [défaut : separate]
|
||||
uniq-help-check-chars = comparer au maximum N caractères dans les lignes
|
||||
uniq-help-count = préfixer les lignes par le nombre d'occurrences
|
||||
uniq-help-ignore-case = ignorer les différences de casse lors de la comparaison
|
||||
uniq-help-repeated = afficher seulement les lignes dupliquées
|
||||
uniq-help-skip-chars = éviter de comparer les N premiers caractères
|
||||
uniq-help-skip-fields = éviter de comparer les N premiers champs
|
||||
uniq-help-unique = afficher seulement les lignes uniques
|
||||
uniq-help-zero-terminated = terminer les lignes avec un octet 0, pas une nouvelle ligne
|
||||
|
||||
# Messages d'erreur
|
||||
uniq-error-write-line-terminator = Impossible d'écrire le terminateur de ligne
|
||||
uniq-error-write-error = erreur d'écriture
|
||||
uniq-error-invalid-argument = Argument invalide pour { $opt_name } : { $arg }
|
||||
uniq-error-try-help = Essayez 'uniq --help' pour plus d'informations.
|
||||
uniq-error-group-mutually-exclusive = --group est mutuellement exclusif avec -c/-d/-D/-u
|
||||
uniq-error-group-badoption = argument invalide 'badoption' pour '--group'
|
||||
Arguments valides :
|
||||
- 'prepend'
|
||||
- 'append'
|
||||
- 'separate'
|
||||
- 'both'
|
||||
|
||||
uniq-error-all-repeated-badoption = argument invalide 'badoption' pour '--all-repeated'
|
||||
Arguments valides :
|
||||
- 'none'
|
||||
- 'prepend'
|
||||
- 'separate'
|
||||
|
||||
uniq-error-counts-and-repeated-meaningless = afficher toutes les lignes dupliquées et les nombres de répétitions n'a pas de sens
|
||||
Essayez 'uniq --help' pour plus d'informations.
|
||||
uniq-error-could-not-open = Impossible d'ouvrir { $path }
|
|
@ -7,6 +7,7 @@ use clap::{
|
|||
Arg, ArgAction, ArgMatches, Command, builder::ValueParser, error::ContextKind, error::Error,
|
||||
error::ErrorKind,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader, BufWriter, Write, stdin, stdout};
|
||||
|
@ -17,7 +18,7 @@ use uucore::format_usage;
|
|||
use uucore::parser::shortcut_value_parser::ShortcutValueParser;
|
||||
use uucore::posix::{OBSOLETE, posix_version};
|
||||
|
||||
use uucore::locale::get_message;
|
||||
use uucore::locale::{get_message, get_message_with_args};
|
||||
|
||||
pub mod options {
|
||||
pub static ALL_REPEATED: &str = "all-repeated";
|
||||
|
@ -60,7 +61,7 @@ macro_rules! write_line_terminator {
|
|||
($writer:expr, $line_terminator:expr) => {
|
||||
$writer
|
||||
.write_all(&[$line_terminator])
|
||||
.map_err_context(|| "Could not write line terminator".to_string())
|
||||
.map_err_context(|| get_message("uniq-error-write-line-terminator"))
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -108,7 +109,9 @@ impl Uniq {
|
|||
{
|
||||
write_line_terminator!(writer, line_terminator)?;
|
||||
}
|
||||
writer.flush().map_err_context(|| "write error".into())?;
|
||||
writer
|
||||
.flush()
|
||||
.map_err_context(|| get_message("uniq-error-write-error"))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -155,7 +158,7 @@ impl Uniq {
|
|||
|
||||
// Skip self.slice_start bytes (if -s was used).
|
||||
// self.slice_start is how many characters to skip, but historically
|
||||
// uniq’s `-s N` means “skip N *bytes*,” so do that literally:
|
||||
// uniq's `-s N` means "skip N *bytes*," so do that literally:
|
||||
let skip_bytes = self.slice_start.unwrap_or(0);
|
||||
let fields_to_check = if skip_bytes < fields_to_check.len() {
|
||||
&fields_to_check[skip_bytes..]
|
||||
|
@ -167,7 +170,7 @@ impl Uniq {
|
|||
// Convert the leftover bytes to UTF-8 for character-based -w
|
||||
// If invalid UTF-8, just compare them as individual bytes (fallback).
|
||||
let Ok(string_after_skip) = std::str::from_utf8(fields_to_check) else {
|
||||
// Fallback: if invalid UTF-8, treat them as single-byte “chars”
|
||||
// Fallback: if invalid UTF-8, treat them as single-byte "chars"
|
||||
return closure(&mut fields_to_check.iter().map(|&b| b as char));
|
||||
};
|
||||
|
||||
|
@ -225,7 +228,7 @@ impl Uniq {
|
|||
} else {
|
||||
writer.write_all(line)
|
||||
}
|
||||
.map_err_context(|| "write error".to_string())?;
|
||||
.map_err_context(|| get_message("uniq-error-write-error"))?;
|
||||
|
||||
write_line_terminator!(writer, line_terminator)
|
||||
}
|
||||
|
@ -239,7 +242,13 @@ fn opt_parsed(opt_name: &str, matches: &ArgMatches) -> UResult<Option<usize>> {
|
|||
IntErrorKind::PosOverflow => Ok(Some(usize::MAX)),
|
||||
_ => Err(USimpleError::new(
|
||||
1,
|
||||
format!("Invalid argument for {opt_name}: {}", arg_str.maybe_quote()),
|
||||
get_message_with_args(
|
||||
"uniq-error-invalid-argument",
|
||||
HashMap::from([
|
||||
("opt_name".to_string(), opt_name.to_string()),
|
||||
("arg".to_string(), arg_str.maybe_quote().to_string()),
|
||||
]),
|
||||
),
|
||||
)),
|
||||
},
|
||||
},
|
||||
|
@ -509,11 +518,11 @@ fn handle_extract_obs_skip_chars(
|
|||
/// for `uniq` hardcode and require the exact wording of the error message
|
||||
/// and it is not compatible with how Clap formats and displays those error messages.
|
||||
fn map_clap_errors(clap_error: Error) -> Box<dyn UError> {
|
||||
let footer = "Try 'uniq --help' for more information.";
|
||||
let override_arg_conflict =
|
||||
"--group is mutually exclusive with -c/-d/-D/-u\n".to_string() + footer;
|
||||
let override_group_badoption = "invalid argument 'badoption' for '--group'\nValid arguments are:\n - 'prepend'\n - 'append'\n - 'separate'\n - 'both'\n".to_string() + footer;
|
||||
let override_all_repeated_badoption = "invalid argument 'badoption' for '--all-repeated'\nValid arguments are:\n - 'none'\n - 'prepend'\n - 'separate'\n".to_string() + footer;
|
||||
let footer = get_message("uniq-error-try-help");
|
||||
let override_arg_conflict = get_message("uniq-error-group-mutually-exclusive") + "\n" + &footer;
|
||||
let override_group_badoption = get_message("uniq-error-group-badoption") + "\n" + &footer;
|
||||
let override_all_repeated_badoption =
|
||||
get_message("uniq-error-all-repeated-badoption") + "\n" + &footer;
|
||||
|
||||
let error_message = match clap_error.kind() {
|
||||
ErrorKind::ArgumentConflict => override_arg_conflict,
|
||||
|
@ -578,7 +587,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
if uniq.show_counts && uniq.all_repeated {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
"printing all duplicated lines and repeat counts is meaningless\nTry 'uniq --help' for more information.",
|
||||
get_message("uniq-error-counts-and-repeated-meaningless"),
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -599,12 +608,8 @@ pub fn uu_app() -> Command {
|
|||
Arg::new(options::ALL_REPEATED)
|
||||
.short('D')
|
||||
.long(options::ALL_REPEATED)
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
"none",
|
||||
"prepend",
|
||||
"separate"
|
||||
]))
|
||||
.help("print all duplicate lines. Delimiting is done with blank lines. [default: none]")
|
||||
.value_parser(ShortcutValueParser::new(["none", "prepend", "separate"]))
|
||||
.help(get_message("uniq-help-all-repeated"))
|
||||
.value_name("delimit-method")
|
||||
.num_args(0..=1)
|
||||
.default_missing_value("none")
|
||||
|
@ -614,12 +619,9 @@ pub fn uu_app() -> Command {
|
|||
Arg::new(options::GROUP)
|
||||
.long(options::GROUP)
|
||||
.value_parser(ShortcutValueParser::new([
|
||||
"separate",
|
||||
"prepend",
|
||||
"append",
|
||||
"both",
|
||||
"separate", "prepend", "append", "both",
|
||||
]))
|
||||
.help("show all items, separating groups with an empty line. [default: separate]")
|
||||
.help(get_message("uniq-help-group"))
|
||||
.value_name("group-method")
|
||||
.num_args(0..=1)
|
||||
.default_missing_value("separate")
|
||||
|
@ -628,63 +630,63 @@ pub fn uu_app() -> Command {
|
|||
options::REPEATED,
|
||||
options::ALL_REPEATED,
|
||||
options::UNIQUE,
|
||||
options::COUNT
|
||||
options::COUNT,
|
||||
]),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::CHECK_CHARS)
|
||||
.short('w')
|
||||
.long(options::CHECK_CHARS)
|
||||
.help("compare no more than N characters in lines")
|
||||
.help(get_message("uniq-help-check-chars"))
|
||||
.value_name("N"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::COUNT)
|
||||
.short('c')
|
||||
.long(options::COUNT)
|
||||
.help("prefix lines by the number of occurrences")
|
||||
.help(get_message("uniq-help-count"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::IGNORE_CASE)
|
||||
.short('i')
|
||||
.long(options::IGNORE_CASE)
|
||||
.help("ignore differences in case when comparing")
|
||||
.help(get_message("uniq-help-ignore-case"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::REPEATED)
|
||||
.short('d')
|
||||
.long(options::REPEATED)
|
||||
.help("only print duplicate lines")
|
||||
.help(get_message("uniq-help-repeated"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::SKIP_CHARS)
|
||||
.short('s')
|
||||
.long(options::SKIP_CHARS)
|
||||
.help("avoid comparing the first N characters")
|
||||
.help(get_message("uniq-help-skip-chars"))
|
||||
.value_name("N"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::SKIP_FIELDS)
|
||||
.short('f')
|
||||
.long(options::SKIP_FIELDS)
|
||||
.help("avoid comparing the first N fields")
|
||||
.help(get_message("uniq-help-skip-fields"))
|
||||
.value_name("N"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::UNIQUE)
|
||||
.short('u')
|
||||
.long(options::UNIQUE)
|
||||
.help("only print unique lines")
|
||||
.help(get_message("uniq-help-unique"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::ZERO_TERMINATED)
|
||||
.short('z')
|
||||
.long(options::ZERO_TERMINATED)
|
||||
.help("end lines with 0 byte, not newline")
|
||||
.help(get_message("uniq-help-zero-terminated"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
|
@ -721,8 +723,12 @@ fn get_delimiter(matches: &ArgMatches) -> Delimiters {
|
|||
fn open_input_file(in_file_name: Option<&OsStr>) -> UResult<Box<dyn BufRead>> {
|
||||
Ok(match in_file_name {
|
||||
Some(path) if path != "-" => {
|
||||
let in_file = File::open(path)
|
||||
.map_err_context(|| format!("Could not open {}", path.maybe_quote()))?;
|
||||
let in_file = File::open(path).map_err_context(|| {
|
||||
get_message_with_args(
|
||||
"uniq-error-could-not-open",
|
||||
HashMap::from([("path".to_string(), path.maybe_quote().to_string())]),
|
||||
)
|
||||
})?;
|
||||
Box::new(BufReader::new(in_file))
|
||||
}
|
||||
_ => Box::new(stdin().lock()),
|
||||
|
@ -733,8 +739,12 @@ fn open_input_file(in_file_name: Option<&OsStr>) -> UResult<Box<dyn BufRead>> {
|
|||
fn open_output_file(out_file_name: Option<&OsStr>) -> UResult<Box<dyn Write>> {
|
||||
Ok(match out_file_name {
|
||||
Some(path) if path != "-" => {
|
||||
let out_file = File::create(path)
|
||||
.map_err_context(|| format!("Could not open {}", path.maybe_quote()))?;
|
||||
let out_file = File::create(path).map_err_context(|| {
|
||||
get_message_with_args(
|
||||
"uniq-error-could-not-open",
|
||||
HashMap::from([("path".to_string(), path.maybe_quote().to_string())]),
|
||||
)
|
||||
})?;
|
||||
Box::new(BufWriter::new(out_file))
|
||||
}
|
||||
_ => Box::new(stdout().lock()),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue