2011-08-05 59 views
9

在殼體內的輸出,我可以做有沒有辦法實現的grep類似功能的Rails的控制檯

$ cat name_of_file_with_a_lot_of_text | grep "What I am looking for" 

內的滑軌控制檯,我可以實現類似的東西,說當我運行一個命令和輸出是巨大的,特別是說一個數據庫查詢。

我知道輸出它作爲YAML,但那不是我正在尋找。

謝謝。

回答

19

是的,你可以。該方法被稱爲gr ...等待它... ep。 Ruby的grep適用於StringArray和許多其他內置對象。例如,要得到一個號碼的所有to_xxx方法,只是做:

1.methods.grep(/to_/) 
+1

不會對輸出的數據庫查詢工作。 – subiet

+1

我只是爆發出笑聲......「gr ..等待它......ep」......就像一個很好的幽默;) – luigi7up

2

我有同樣的問題,是不是很滿意,從ream88有點尖刻迴應,所以我決定採取裂紋它。

# Allows you to filter output to the console using grep 
# Ex: 
# def foo 
#  puts "Some debugging output here" 
#  puts "The value of x is y" 
#  puts "The value of foo is bar" 
# end 
# 
# grep_stdout(/value/) { foo } 
# # => The value of x is y 
# # => The value of foo is bar 
# # => nil 
def grep_stdout(expression) 
    # First we need to create a ruby "pipe" which is two sets of IO subclasses 
    # the first is read only (which represents a fake $stdin) and the second is 
    # write only (which represents a fake $stdout). 
    placeholder_in, placeholder_out = IO.pipe 

    # This child process handles the grep'ing. Its done in a child process so that 
    # it can operate in parallel with the main process. 
    pid = fork { 
    # sync $stdout so we can report any matches asap 
    $stdout.sync 

    # replace $stdout with placeholder_out 
    $stdin.reopen(placeholder_in) 

    # we have to close both placeholder_out and placeholder_in because all instances 
    # of an IO stream must be closed in order for it to ever reach EOF. There's two 
    # in this method; one in the child process and one in the main process. 
    placeholder_in.close 
    placeholder_out.close 

    # loop continuously until we reach EOF (which happens when all 
    # instances of placeholder_out have closed) 
    read_buffer = '' 
    loop do 
     begin 
     read_buffer << $stdin.readpartial(4096) 
     if line_match = read_buffer.match(/(.*\n)(.*)/) 
      print line_match[1].grep(expression) # grep complete lines 
      read_buffer = line_match[2]   # save remaining partial line for the next iteration 
     end 
     rescue EOFError 
     print read_buffer.grep(expression) # grep any remaining partial line at EOF 
     break 
     end 
    end 
    } 

    # Save the original stdout out to a variable so we can use it again after this 
    # method is done 
    original_stdout = $stdout 

    # Redirect stdout to our pipe 
    $stdout = placeholder_out 

    # sync $stdout so that we can start operating on it as soon as possible 
    $stdout.sync 

    # allow the block to execute and save its return value 
    return_value = yield 

    # Set stdout back to the original so output will flow again 
    $stdout = original_stdout 

    # close the main instances of placeholder_in and placeholder_out 
    placeholder_in.close 
    placeholder_out.close 

    # Wait for the child processes to finish 
    Process.wait pid 

    # Because the connection to the database has a tendency to go away when calling this, reconnect here 
    # if we're using ActiveRecord 
    if defined?(ActiveRecord) 
    suppress_stdout { ActiveRecord::Base.verify_active_connections! } 
    end 

    # return the value of the block 
    return_value 
end 

我的解決方案的明顯缺點是輸出丟失。我不知道如何解決這個問題,而不需要撥打yield兩次。

編輯我已經改變了我的答案,只撥打fork一次,它允許我保留塊的輸出並在最後返回它。贏得。

EDIT 2您可以在此寶石獲得所有這些功能(和更多!)現在https://github.com/FutureAdvisor/console_util

相關問題