Selected field assignment


#1

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,


#2

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 :wink:


#3

On Tue, Nov 18, 2008 at 11:51 AM, Bil K. 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


#4

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 :wink:

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/


#5

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


#6

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,


#7

— On Tue, 11/18/08, Bil K. 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

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


#8

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

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

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

Regards,