0

I'm writing a program to parse data from /proc/pid/stat, but don't know how to parse those fields using idiomatic rust. The second field can contain anything, including space and parenthesis.

/proc/pid/stat look like this:

802359 (cat) R 728674 802359 728674 34824 802359 4194304 92 0 0 0 0 0 0 0 20 0 1 0 10550623 11358208 132 18446744073709551615 94492582699008 94492582716465 140732240338192 0 0 0 0 0 0 0 0 0 17 7 0 0 0 0 0 94492582734480 94492582736064 94492600344576 140732240341139 140732240341159 140732240341159 140732240343019 0
Herohtar
  • 5,347
  • 4
  • 31
  • 41
William Taylor
  • 549
  • 3
  • 22
  • 5
    Given that the second field starts with `(` and ends with `)`, and that there can be no parentheses in the other fields, just use [`find`](https://doc.rust-lang.org/1.54.0/std/primitive.str.html#method.find) and [`rfind`](https://doc.rust-lang.org/1.54.0/std/primitive.str.html#method.rfind) to find the boundaries of the second field, and [`split`](https://doc.rust-lang.org/1.54.0/std/primitive.str.html#method.split) to parse the other fields. – Jmb Jan 28 '22 at 11:07

1 Answers1

1

Try this:

let s = "802359 (cat foo bar) R 728674 802359 728674 34824 802359 4194304 92 0 0 0 0 0 0 0 20 0 1 0 10550623 11358208 132 18446744073709551615 94492582699008 94492582716465 140732240338192 0 0 0 0 0 0 0 0 0 17 7 0 0 0 0 0 94492582734480 94492582736064 94492600344576 140732240341139 140732240341159 140732240341159 140732240343019 0";
let field2 = s
    .chars()
    .skip_while(|&x| x != '(')
    .take_while(|&x| x != ')')
    .collect::<String>()
    + ")";
println!("{:?}", field2);

You can do something similar with split_ascii_whitespace() instead of chars() to parse the whole string.

marcantonio
  • 958
  • 10
  • 24
  • 1
    The second field can contain ')' so your code can product wrong result. I think find and rfind should do it, as @Jmb pointed out. – William Taylor Jan 29 '22 at 04:56