mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
l10n: port uniq to translation + add french
This commit is contained in:
parent
a769fc7904
commit
f3900fadde
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.
|
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.
|
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,
|
Arg, ArgAction, ArgMatches, Command, builder::ValueParser, error::ContextKind, error::Error,
|
||||||
error::ErrorKind,
|
error::ErrorKind,
|
||||||
};
|
};
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::ffi::{OsStr, OsString};
|
use std::ffi::{OsStr, OsString};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader, BufWriter, Write, stdin, stdout};
|
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::parser::shortcut_value_parser::ShortcutValueParser;
|
||||||
use uucore::posix::{OBSOLETE, posix_version};
|
use uucore::posix::{OBSOLETE, posix_version};
|
||||||
|
|
||||||
use uucore::locale::get_message;
|
use uucore::locale::{get_message, get_message_with_args};
|
||||||
|
|
||||||
pub mod options {
|
pub mod options {
|
||||||
pub static ALL_REPEATED: &str = "all-repeated";
|
pub static ALL_REPEATED: &str = "all-repeated";
|
||||||
|
@ -60,7 +61,7 @@ macro_rules! write_line_terminator {
|
||||||
($writer:expr, $line_terminator:expr) => {
|
($writer:expr, $line_terminator:expr) => {
|
||||||
$writer
|
$writer
|
||||||
.write_all(&[$line_terminator])
|
.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)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +158,7 @@ impl Uniq {
|
||||||
|
|
||||||
// Skip self.slice_start bytes (if -s was used).
|
// Skip self.slice_start bytes (if -s was used).
|
||||||
// self.slice_start is how many characters to skip, but historically
|
// 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 skip_bytes = self.slice_start.unwrap_or(0);
|
||||||
let fields_to_check = if skip_bytes < fields_to_check.len() {
|
let fields_to_check = if skip_bytes < fields_to_check.len() {
|
||||||
&fields_to_check[skip_bytes..]
|
&fields_to_check[skip_bytes..]
|
||||||
|
@ -167,7 +170,7 @@ impl Uniq {
|
||||||
// Convert the leftover bytes to UTF-8 for character-based -w
|
// Convert the leftover bytes to UTF-8 for character-based -w
|
||||||
// If invalid UTF-8, just compare them as individual bytes (fallback).
|
// If invalid UTF-8, just compare them as individual bytes (fallback).
|
||||||
let Ok(string_after_skip) = std::str::from_utf8(fields_to_check) else {
|
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));
|
return closure(&mut fields_to_check.iter().map(|&b| b as char));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -225,7 +228,7 @@ impl Uniq {
|
||||||
} else {
|
} else {
|
||||||
writer.write_all(line)
|
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)
|
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)),
|
IntErrorKind::PosOverflow => Ok(Some(usize::MAX)),
|
||||||
_ => Err(USimpleError::new(
|
_ => Err(USimpleError::new(
|
||||||
1,
|
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
|
/// 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.
|
/// and it is not compatible with how Clap formats and displays those error messages.
|
||||||
fn map_clap_errors(clap_error: Error) -> Box<dyn UError> {
|
fn map_clap_errors(clap_error: Error) -> Box<dyn UError> {
|
||||||
let footer = "Try 'uniq --help' for more information.";
|
let footer = get_message("uniq-error-try-help");
|
||||||
let override_arg_conflict =
|
let override_arg_conflict = get_message("uniq-error-group-mutually-exclusive") + "\n" + &footer;
|
||||||
"--group is mutually exclusive with -c/-d/-D/-u\n".to_string() + footer;
|
let override_group_badoption = get_message("uniq-error-group-badoption") + "\n" + &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 =
|
||||||
let override_all_repeated_badoption = "invalid argument 'badoption' for '--all-repeated'\nValid arguments are:\n - 'none'\n - 'prepend'\n - 'separate'\n".to_string() + footer;
|
get_message("uniq-error-all-repeated-badoption") + "\n" + &footer;
|
||||||
|
|
||||||
let error_message = match clap_error.kind() {
|
let error_message = match clap_error.kind() {
|
||||||
ErrorKind::ArgumentConflict => override_arg_conflict,
|
ErrorKind::ArgumentConflict => override_arg_conflict,
|
||||||
|
@ -578,7 +587,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
if uniq.show_counts && uniq.all_repeated {
|
if uniq.show_counts && uniq.all_repeated {
|
||||||
return Err(USimpleError::new(
|
return Err(USimpleError::new(
|
||||||
1,
|
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)
|
Arg::new(options::ALL_REPEATED)
|
||||||
.short('D')
|
.short('D')
|
||||||
.long(options::ALL_REPEATED)
|
.long(options::ALL_REPEATED)
|
||||||
.value_parser(ShortcutValueParser::new([
|
.value_parser(ShortcutValueParser::new(["none", "prepend", "separate"]))
|
||||||
"none",
|
.help(get_message("uniq-help-all-repeated"))
|
||||||
"prepend",
|
|
||||||
"separate"
|
|
||||||
]))
|
|
||||||
.help("print all duplicate lines. Delimiting is done with blank lines. [default: none]")
|
|
||||||
.value_name("delimit-method")
|
.value_name("delimit-method")
|
||||||
.num_args(0..=1)
|
.num_args(0..=1)
|
||||||
.default_missing_value("none")
|
.default_missing_value("none")
|
||||||
|
@ -614,12 +619,9 @@ pub fn uu_app() -> Command {
|
||||||
Arg::new(options::GROUP)
|
Arg::new(options::GROUP)
|
||||||
.long(options::GROUP)
|
.long(options::GROUP)
|
||||||
.value_parser(ShortcutValueParser::new([
|
.value_parser(ShortcutValueParser::new([
|
||||||
"separate",
|
"separate", "prepend", "append", "both",
|
||||||
"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")
|
.value_name("group-method")
|
||||||
.num_args(0..=1)
|
.num_args(0..=1)
|
||||||
.default_missing_value("separate")
|
.default_missing_value("separate")
|
||||||
|
@ -628,63 +630,63 @@ pub fn uu_app() -> Command {
|
||||||
options::REPEATED,
|
options::REPEATED,
|
||||||
options::ALL_REPEATED,
|
options::ALL_REPEATED,
|
||||||
options::UNIQUE,
|
options::UNIQUE,
|
||||||
options::COUNT
|
options::COUNT,
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::CHECK_CHARS)
|
Arg::new(options::CHECK_CHARS)
|
||||||
.short('w')
|
.short('w')
|
||||||
.long(options::CHECK_CHARS)
|
.long(options::CHECK_CHARS)
|
||||||
.help("compare no more than N characters in lines")
|
.help(get_message("uniq-help-check-chars"))
|
||||||
.value_name("N"),
|
.value_name("N"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::COUNT)
|
Arg::new(options::COUNT)
|
||||||
.short('c')
|
.short('c')
|
||||||
.long(options::COUNT)
|
.long(options::COUNT)
|
||||||
.help("prefix lines by the number of occurrences")
|
.help(get_message("uniq-help-count"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::IGNORE_CASE)
|
Arg::new(options::IGNORE_CASE)
|
||||||
.short('i')
|
.short('i')
|
||||||
.long(options::IGNORE_CASE)
|
.long(options::IGNORE_CASE)
|
||||||
.help("ignore differences in case when comparing")
|
.help(get_message("uniq-help-ignore-case"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::REPEATED)
|
Arg::new(options::REPEATED)
|
||||||
.short('d')
|
.short('d')
|
||||||
.long(options::REPEATED)
|
.long(options::REPEATED)
|
||||||
.help("only print duplicate lines")
|
.help(get_message("uniq-help-repeated"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::SKIP_CHARS)
|
Arg::new(options::SKIP_CHARS)
|
||||||
.short('s')
|
.short('s')
|
||||||
.long(options::SKIP_CHARS)
|
.long(options::SKIP_CHARS)
|
||||||
.help("avoid comparing the first N characters")
|
.help(get_message("uniq-help-skip-chars"))
|
||||||
.value_name("N"),
|
.value_name("N"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::SKIP_FIELDS)
|
Arg::new(options::SKIP_FIELDS)
|
||||||
.short('f')
|
.short('f')
|
||||||
.long(options::SKIP_FIELDS)
|
.long(options::SKIP_FIELDS)
|
||||||
.help("avoid comparing the first N fields")
|
.help(get_message("uniq-help-skip-fields"))
|
||||||
.value_name("N"),
|
.value_name("N"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::UNIQUE)
|
Arg::new(options::UNIQUE)
|
||||||
.short('u')
|
.short('u')
|
||||||
.long(options::UNIQUE)
|
.long(options::UNIQUE)
|
||||||
.help("only print unique lines")
|
.help(get_message("uniq-help-unique"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::ZERO_TERMINATED)
|
Arg::new(options::ZERO_TERMINATED)
|
||||||
.short('z')
|
.short('z')
|
||||||
.long(options::ZERO_TERMINATED)
|
.long(options::ZERO_TERMINATED)
|
||||||
.help("end lines with 0 byte, not newline")
|
.help(get_message("uniq-help-zero-terminated"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -721,8 +723,12 @@ fn get_delimiter(matches: &ArgMatches) -> Delimiters {
|
||||||
fn open_input_file(in_file_name: Option<&OsStr>) -> UResult<Box<dyn BufRead>> {
|
fn open_input_file(in_file_name: Option<&OsStr>) -> UResult<Box<dyn BufRead>> {
|
||||||
Ok(match in_file_name {
|
Ok(match in_file_name {
|
||||||
Some(path) if path != "-" => {
|
Some(path) if path != "-" => {
|
||||||
let in_file = File::open(path)
|
let in_file = File::open(path).map_err_context(|| {
|
||||||
.map_err_context(|| format!("Could not open {}", path.maybe_quote()))?;
|
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(BufReader::new(in_file))
|
||||||
}
|
}
|
||||||
_ => Box::new(stdin().lock()),
|
_ => 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>> {
|
fn open_output_file(out_file_name: Option<&OsStr>) -> UResult<Box<dyn Write>> {
|
||||||
Ok(match out_file_name {
|
Ok(match out_file_name {
|
||||||
Some(path) if path != "-" => {
|
Some(path) if path != "-" => {
|
||||||
let out_file = File::create(path)
|
let out_file = File::create(path).map_err_context(|| {
|
||||||
.map_err_context(|| format!("Could not open {}", path.maybe_quote()))?;
|
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(BufWriter::new(out_file))
|
||||||
}
|
}
|
||||||
_ => Box::new(stdout().lock()),
|
_ => Box::new(stdout().lock()),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue