mirror of
https://github.com/uutils/coreutils
synced 2024-11-17 02:08:09 +00:00
du: Add threshold argument support
- Add --threshold parameter and corresponding logic to skip listing entires that don't adhere to the threshold
This commit is contained in:
parent
440eba628c
commit
d6181ce7d4
1 changed files with 52 additions and 0 deletions
|
@ -28,6 +28,7 @@ use std::os::windows::io::AsRawHandle;
|
|||
#[cfg(windows)]
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::time::{Duration, UNIX_EPOCH};
|
||||
use uucore::parse_size::{parse_size, ParseSizeError};
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
@ -56,6 +57,7 @@ mod options {
|
|||
pub const BLOCK_SIZE_1M: &str = "m";
|
||||
pub const SEPARATE_DIRS: &str = "S";
|
||||
pub const SUMMARIZE: &str = "s";
|
||||
pub const THRESHOLD: &str = "threshold";
|
||||
pub const SI: &str = "si";
|
||||
pub const TIME: &str = "time";
|
||||
pub const TIME_STYLE: &str = "time-style";
|
||||
|
@ -510,6 +512,17 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.long(options::ONE_FILE_SYSTEM)
|
||||
.help("skip directories on different file systems")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::THRESHOLD)
|
||||
.short("t")
|
||||
.long(options::THRESHOLD)
|
||||
.alias("th")
|
||||
.value_name("SIZE")
|
||||
.number_of_values(1)
|
||||
.allow_hyphen_values(true)
|
||||
.help("exclude entries smaller than SIZE if positive, \
|
||||
or entries greater than SIZE if negative")
|
||||
)
|
||||
// .arg(
|
||||
// Arg::with_name("")
|
||||
// .short("x")
|
||||
|
@ -586,6 +599,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
let block_size = u64::try_from(read_block_size(matches.value_of(options::BLOCK_SIZE))).unwrap();
|
||||
|
||||
let threshold = match matches.value_of(options::THRESHOLD) {
|
||||
Some(s) => Threshold::from_str(s)
|
||||
.unwrap_or_else(|e| crash!(1, "{}", format_error_message(e, s, options::THRESHOLD))),
|
||||
None => Threshold(None, false),
|
||||
};
|
||||
|
||||
let multiplier: u64 = if matches.is_present(options::SI) {
|
||||
1000
|
||||
} else {
|
||||
|
@ -654,6 +673,10 @@ Try '{} --help' for more information.",
|
|||
// See: http://linux.die.net/man/2/stat
|
||||
stat.blocks * 512
|
||||
};
|
||||
if threshold.should_exclude(size) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if matches.is_present(options::TIME) {
|
||||
let tm = {
|
||||
let secs = {
|
||||
|
@ -720,6 +743,35 @@ Try '{} --help' for more information.",
|
|||
0
|
||||
}
|
||||
|
||||
struct Threshold(Option<u64>, bool);
|
||||
|
||||
impl FromStr for Threshold {
|
||||
type Err = ParseSizeError;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
let offset = if s.starts_with('-') || s.starts_with('+') {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let sz = parse_size(&s[offset..])?;
|
||||
|
||||
Ok(Threshold(
|
||||
Some(u64::try_from(sz).unwrap()),
|
||||
s.starts_with('-'),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl Threshold {
|
||||
fn should_exclude(&self, sz: u64) -> bool {
|
||||
match *self {
|
||||
Threshold(Some(th), is_upper) => (is_upper && sz > th) || (!is_upper && sz < th),
|
||||
Threshold(None, _) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn format_error_message(error: ParseSizeError, s: &str, option: &str) -> String {
|
||||
// NOTE:
|
||||
// GNU's du echos affected flag, -B or --block-size (-t or --threshold), depending user's selection
|
||||
|
|
Loading…
Reference in a new issue