# Selected field assignment

**URL:** <https://www.ruby-forum.com/t/selected-field-assignment/153540>\
**Category:** Ruby\
**Created:** [November 18, 2008, 2:55pm UTC](https://www.ruby-forum.com/t/selected-field-assignment/153540 "2008-11-18T14:55:47Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bil\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/848f3c/32.png) [@Bil\_K](https://www.ruby-forum.com/u/Bil_K)\
**Post date:** [November 18, 2008, 2:55pm UTC](https://www.ruby-forum.com/t/selected-field-assignment/153540/1 "2008-11-18T14:55:47Z")

</div>

Hi,

I’m grabbing the owner and file names from `find . -perm -g+r -ls`  
which has ls -dgils output like,

6744065 8 -rw-r–r-- 1 kleb users 289 Nov 30  
2007 Ruby/README

with something like,

find\_result.each\_line do |line|  
fields = line.split  
user\_name, file\_name = fields[4], fields.last

I’ve also played with,

_,_,_,_,user,_,_,_,_,\_,file = a.split

But both leave me thinking there is a better way without resorting  
to a regex?

Thanks,

---

<div class="post-metadata">

**Author:** ![Bil\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/848f3c/32.png) [@Bil\_K](https://www.ruby-forum.com/u/Bil_K)\
**Post date:** [November 18, 2008, 4:31pm UTC](https://www.ruby-forum.com/t/selected-field-assignment/153540/2 "2008-11-18T16:31:39Z")

</div>

On Nov 18, 2008, at 6:51 AM, Bil K. wrote:

> find\_result.each\_line do |line|  
> fields = line.split  
> user\_name, file\_name = fields[4], fields.last
> 
> I’ve also played with,
> 
> _,_,_,_,user,_,_,_,_,\_,file = a.split
> 
> But both leave me thinking there is a better way without resorting  
> to a regex?

class LsInfo \<  
Struct  
.new  
(:a  
, :b  
, :permissions  
, :type, :user, :group, :size, :month, :day, :year\_or\_time, :file)

def initialize( string )  
super(\*string.split)  
end  
end

info = []  
find\_result.each\_line do |line|  
info = LsInfo.new(line)  
end

info.first.user  
info.last.file

Not being up to snuff on the output format of ls, you’ll have to  
appropriately name “a” and “b” and whatever else I mislabeled in the  
example above.

Blessings,  
TwP

PS Thanks for singlehandedly keeping the space shuttle flying with  
your 42 line ruby script 😉

---

<div class="post-metadata">

**Author:** ![Bil\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/848f3c/32.png) [@Bil\_K](https://www.ruby-forum.com/u/Bil_K)\
**Post date:** [November 18, 2008, 9:51pm UTC](https://www.ruby-forum.com/t/selected-field-assignment/153540/3 "2008-11-18T21:51:38Z")

</div>

On Tue, Nov 18, 2008 at 11:51 AM, Bil K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> find\_result.each\_line do |line|  
> fields = line.split  
> user\_name, file\_name = fields[4], fields.last
> 
> I’ve also played with,
> 
> _,_,_,_,user,_,_,_,_,\_,file = a.split
> 
> But both leave me thinking there is a better way without resorting  
> to a regex?

owner, file = string.split.values\_at(4, -1)

It relies on the output being the same format. For other cases a regex  
would be better.

Diogo

---

<div class="post-metadata">

**Author:** ![Bil\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/848f3c/32.png) [@Bil\_K](https://www.ruby-forum.com/u/Bil_K)\
**Post date:** [November 18, 2008, 11:46pm UTC](https://www.ruby-forum.com/t/selected-field-assignment/153540/4 "2008-11-18T23:46:38Z")

</div>

On Nov 18, 2008, at 6:51 AM, Bil K. wrote:

> find\_result.each\_line do |line|  
> fields = line.split  
> user\_name, file\_name = fields[4], fields.last
> 
> I’ve also played with,
> 
> _,_,_,_,user,_,_,_,_,\_,file = a.split
> 
> But both leave me thinking there is a better way without resorting  
> to a regex?

given that you have an array, and fields, you could use arrayfields 😉

a = Array.fields %w( size foo mode bar user group )

find\_result.each\_line do |line|  
a.replace line.split

p a[‘user’]  
end

a @ [http://codeforpeople.com/](http://codeforpeople.com/)

---

<div class="post-metadata">

**Author:** ![Bil\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/848f3c/32.png) [@Bil\_K](https://www.ruby-forum.com/u/Bil_K)\
**Post date:** [November 19, 2008, 7:02am UTC](https://www.ruby-forum.com/t/selected-field-assignment/153540/5 "2008-11-19T07:02:28Z")

</div>

On Tue, Nov 18, 2008 at 10:51:29PM +0900, Bil K. wrote:

> find\_result.each\_line do |line|  
> fields = line.split  
> user\_name, file\_name = fields[4], fields.last
> 
> I’ve also played with,
> 
> _,_,_,_,user,_,_,_,_,\_,file = a.split
> 
> But both leave me thinking there is a better way without resorting  
> to a regex?

How about this crazy method if you have a find(1) which has -printf.

% ruby eval-find.rb  
Executing command: find . -perm -g+r -type f -printf ’ “%p” =\>  
“%u”,\n’ \>\> file\_listing.rb  
Found 17306 files

% find . -perm -g+r -type f | wc -l  
17306

% cat eval-find.rb  
#!/usr/bin/env ruby

dir = ARGV.shift || “.”

file\_listing = “file\_listing.rb”

# opening brace for hash

File.open( file\_listing, “w+” ) { |f| f.puts “{” }

# use find to dump files to an evalable hash format

format = " “%p” =\> “%u”,\n"  
cmd = “find #{dir} -perm -g+r -type f -printf ‘#{format}’ \>\>  
#{file\_listing}”  
puts “Executing command: #{cmd}”  
%x[#{cmd}]

# closing brace for hash

File.open( file\_listing, “a” ) { |f| f.puts “}” }

# now eval the hash

listing = eval( IO.read( file\_listing) )  
puts “Found #{listing.size} files”

enjoy,

-jeremy

---

<div class="post-metadata">

**Author:** ![Bil\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/848f3c/32.png) [@Bil\_K](https://www.ruby-forum.com/u/Bil_K)\
**Post date:** [November 19, 2008, 6:35pm UTC](https://www.ruby-forum.com/t/selected-field-assignment/153540/6 "2008-11-19T18:35:38Z")

</div>

Diogo L. wrote:

> Bil K. wrote:
> 
> > fields = line.split  
> > user\_name, file\_name = fields[4], fields.last
> 
> owner, file = string.split.values\_at(4, -1)

Perfect!

Thanks,

---

<div class="post-metadata">

**Author:** ![Bil\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/848f3c/32.png) [@Bil\_K](https://www.ruby-forum.com/u/Bil_K)\
**Post date:** [November 19, 2008, 7:41am UTC](https://www.ruby-forum.com/t/selected-field-assignment/153540/7 "2008-11-19T07:41:39Z")

</div>

— On Tue, 11/18/08, Bil K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 6744065 8 -rw-r–r-- 1 kleb users
> 
> _,_,_,_,user,_,_,_,_,\_,file = a.split
> 
> But both leave me thinking there is a better way without  
> resorting  
> to a regex?
> 
> ## Thanks,
> 
> [http://twitter.com/bil\_kleb](http://twitter.com/bil_kleb)

looks like you got several possible suggestions.  
here is one more, not exact but plausible.

avoid system calls, do it all in ruby.

#!/usr/bin/env ruby

require ‘find’  
require ‘etc’

path = ENV[“HOME”]+‘/ruby’

Find.find(path) do |file|  
if FileTest.directory?(file)  
if File.basename(path)[0] == ?.  
Find.prune  
else  
next  
end  
else  
f = File.new(file)  
s = f.stat  
g\_read = sprintf(“%o”, s.mode)  
if ( g\_read.to\_i \>= 100640 )  
print “file: #{file}\t”  
puts “owner: #{Etc.getpwuid(s.uid).name}”  
end  
end  
end

---

<div class="post-metadata">

**Author:** ![Bil\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/848f3c/32.png) [@Bil\_K](https://www.ruby-forum.com/u/Bil_K)\
**Post date:** [November 19, 2008, 6:40pm UTC](https://www.ruby-forum.com/t/selected-field-assignment/153540/8 "2008-11-19T18:40:56Z")

</div>

david wright wrote:

> avoid system calls, do it all in ruby.

I tried that route, see

[http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/320400](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/320400)

I am not satisfied with the mixed abstraction levels.

Meanwhile, Daniel B. is busy fixing up file-find  
to suit:

[http://rubyforge.org/tracker/index.php?group\_id=735&atid=2912](http://rubyforge.org/tracker/index.php?group_id=735&atid=2912)

(He’s already gotten symbolic user names into 0.2.2.)

Regards,
