How to Split a Directory String in Ruby

How to split a directory string in Ruby?

There's no built-in function to split a path into its component directories like there is to join them, but you can try to fake it in a cross-platform way:

directory_string.split(File::SEPARATOR)

This works with relative paths and on non-Unix platforms, but for a path that starts with "/" as the root directory, then you'll get an empty string as your first element in the array, and we'd want "/" instead.

directory_string.split(File::SEPARATOR).map {|x| x=="" ? File::SEPARATOR : x}

If you want just the directories without the root directory like you mentioned above, then you can change it to select from the first element on.

directory_string.split(File::SEPARATOR).map {|x| x=="" ? File::SEPARATOR : x}[1..-1]

Strip the last path directory from path string in Ruby/Rails

Using Pathname is a little bit faster than split. On my machine, running a million times:

require 'benchmark'
require 'pathname'

n = 1000000
id = "id"
Benchmark.bm do |x|
x.report("pathname: ") { n.times { Pathname("/my/to/somewhere/id").dirname.to_s } }
x.report("split:") { n.times { "/my/to/somewhere/id".split('/')[0...-1].join('/') } }
x.report("path.sub:") { n.times { "/my/to/somewhere/id".sub("/#{id}", '') } }
end

I have got the following results:

              user     system      total        real
pathname: 1.550000 0.000000 1.550000 ( 1.549925)
split: 1.810000 0.000000 1.810000 ( 1.806914)
path.sub: 1.030000 0.000000 1.030000 ( 1.030306)

How to split a string which contains multiple forward slashes

I think, this should help you:

string = './component/unit'

string.split('./')
#=> ["", "component/unit"]

string.split('./').last
#=> "component/unit"

Split the string to get only the first 5 characters

You can't be in multiple cwds simultaneously. To run the command for each directory that matches the pattern, you can use Dir#glob:

Dir.glob('/var/cache/acpchef/src/ap-kernelmodule-10*').each do |cwd|
Mixlib::ShellOut.new("command run here", cwd: cwd).run_command
end

Faster and cleaner way to split a string into a path

Use pathname:

require 'pathname'

str = "/some/path/to/some/file.ext"

p = Pathname.new str

path, dir, file = [p.dirname.parent, p.parent.basename, p.basename].map(&:to_s)

p( [path, dir, file] )

It runs great on all versions.

Here you can see it in action.

How to split a string in Ruby and get all items except the first one?

Try this:

first, *rest = ex.split(/, /)

Now first will be the first value, rest will be the rest of the array.

Ruby String Split on \t loses \n

If this is for production, you should be using the CSV class as @DmitryZ pointed out in the comments. CSV processing has a surprising number of caveats and you should not do it by hand.

But let's go through it as an exercise...


The problem is split does not keep the delimiter, and it does not keep trailing null columns. You've hit both issues.

When you run a = text.split(/\n/) then the elements of a do not have newlines.

a = [
171\t1000\t21\t
269\t1000\t25\t
389\t1000\t40\t
1020\t1-03\t30\t1
1058\t1-03\t30\t1
1074\t1-03\t30\t1
200\t300\t\t500
]

Then, as documented in String#split, "if the limit parameter is omitted, trailing null fields are suppressed.", so u = i.split(/\t/) will ignore that last field unless you give it a limit.

If you know it's always going to be 4 fields, you can use 4.

u = i.split(/\t/, 4)

But it's probably more flexible to use -1 because "If [the limit is] negative, there is no limit to the number of fields returned, and trailing null fields are not suppressed." so that will keep the empty fields without hard coding the number of columns in the CSV.

u = i.split(/\t/, -1)

How to extract path from a string in ruby (between 1st and last fwd slash inclusive)

If your file has the always the same structure you could do it without a regex too.

line = '"output_path":"/data/server/output/1/test_file.txt","text":'

path = line.split(/:"|",/)[1]
# => "/data/server/output/1/test_file.txt"

basename = File.basename(path)
# => "test_file.txt"

File.dirname(path) + '/'
# => "/data/server/output/1/"


Related Topics



Leave a reply



Submit