Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use std.split pattern argument? #9

Closed
Jackman3005 opened this issue Apr 27, 2022 · 5 comments
Closed

How to use std.split pattern argument? #9

Jackman3005 opened this issue Apr 27, 2022 · 5 comments

Comments

@Jackman3005
Copy link

Hello, I was playing around with hush tonight and wanted to split a line based on whitespace and was struggling to get a pattern to work. I dug through the docs and the repo and couldn't find any information on how it splits on pattern and what type of patterns it supports.

I noticed that the std.split implementation calls a split_str method. I'm no rust developer, so I'm not sure exactly what's happening in that code, but I was unable to follow any further to figure out what split_str does with the provided pattern.

Here's the code I'm playing with:

#!/usr/bin/env hush

if std.len(std.args()) == 0 then
  std.panic("please pass the port as the first argument")
end


let port = std.args()[0] # 8080
let result = ${
  lsof -i :$port
}

if std.is_empty(result.stdout) then
  std.print("nothing running on port " ++ port)
else
  let lines = std.split(std.trim(result.stdout), "\n")
  # std.print("\noutput: \n" ++ std.to_string(lines))

  for process_line in std.iter(lines) do
    let fields = std.split(std.trim(process_line), "[ \t\n]+")
    std.print("fields: \n" ++ std.to_string(fields))
  end
end

With the following output:

$ ./hello.hsh 8080
fields:
[ "COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME" ]
fields:
[ "java    34304 jack  160u  IPv6 0xf0ea0eac809f015d      0t0  TCP *:http-alt (LISTEN)" ]

tl;dr how to split a string based on a regex pattern?

@Jackman3005
Copy link
Author

Side question... how do I take a range of elements from an array? Specifically where I do not know the length of the elements. Using the example above, I would like to skip the first line of output (I know I could clean the output before it enters hush) and only process the one or more following lines of output. Python has a short syntax for this like the following: lines[1:].

I've been enjoying hush otherwise. Thanks for making something fun to try out, your docs were enjoyable :)

@gahag
Copy link
Collaborator

gahag commented Apr 27, 2022

A regex API is surely a must, and it's on my high priority list. Currently, std.split operates only on literal strings. I have a design in mind, and the implementation shouldn't take much work, so I'll try to implement it until this weekend.

Regarding slicing the array, I would be more favorable to using an iterator in that case. To skip the first line, you could do:

let iter = std.iter(lines)
iter() # skip first line
for line in iter do
  # ...
end

@gahag
Copy link
Collaborator

gahag commented Apr 27, 2022

I have made a new release with an API for regex. Take a look at std.regex

Your script using this new API would be:

#!/usr/bin/env hush

if std.len(std.args()) == 0 then
  std.panic("please pass the port as the first argument")
end


let port = std.args()[0] # 8080
let result = ${
  lsof -i :$port
}

if std.is_empty(result.stdout) then
  std.print("nothing running on port " ++ port)
else
  let spaces = std.regex("[ \t\n]+")
  let lines = std.iter(std.split(std.trim(result.stdout), "\n"))
  # std.print("\noutput: \n" ++ std.to_string(lines))

  lines() # skip header line
  for process_line in lines do
    let fields = spaces.split(std.trim(process_line))
    std.print("fields: \n" ++ std.to_string(fields))
  end
end

Outputs:

fields: 
[ "python", "13808", "gahag", "3u", "IPv4", "120680", "0t0", "TCP", "*:irdmi", "(LISTEN)" ]

@Jackman3005
Copy link
Author

Jackman3005 commented Apr 28, 2022

Amazing! Thanks for the quick turn-around. I'll play with it again soon :)

@Jackman3005
Copy link
Author

Tested it out, everything works as expected so far. Closing the issue for now. Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants