I have been using this so far
system 'strings binary-file.dmp | grep search_string'
Is there something more "Ruby like"?
Here is my quick-and-dirty strings.rb:
#! /usr/bin/ruby
ARGV.each do |filename|
File.open filename,"rb" do |f|
f.each_line do |line|
line.scan(/([\x32-\x7e]{4,})/).each {|a| puts a[0]}
end
end
end
This is not a work of art or anything - it only works in straight US-ASCII. The regex bascially means "all groups of printable US-ASCII characters of size 4 charaters or more". This is essentially what strings(1) does.
Related
Im triying to use this code but not work
ruby -a -F';' -ne if $F[2]<4 'puts $F[3]' ppp.txt
this is my file
mmm;2;nsfnjd
sadjjasjnsd;6;gdhjsd
gsduhdssdj;3;gsdhjhjsd
what is doing worng Please help me
First of all, instead of treating Ruby like some kind of fancy Perl and writing scripts like that, let's expand it into the Ruby code equivalent for clarity:
$; = ';'
while gets
$F = $_.split
if $F[2]<4
puts $F[3]
end
end
Your original code doesn't work, it can't possibly work because it's not valid Ruby code, and further, you're not properly quoting it to pass through the -e evaluation term. Trying to run it I get:
-bash: 4: No such file or directory
You're also presuming the array is 1-indexed, but it's not. It's 0-indexed. Additionally Ruby treats integer values as completely different from strings, never equivalent, not auto-converted. As such you need to call .to_i to convert.
Here's a re-written program that does the job:
File.open(ARGV[0]) do |fi|
fi.readlines.each do |line|
parts = line.chomp.split(';')
if parts[1].to_i < 4
puts parts[2]
end
end
end
I solved with this
ruby -a -F';' -ne ' if $F[1] < "4" ;puts $F[2] end ' ppp.txt
I have a following file:
old_file
new_file
Some string.
end
Text in the middle that is not supposed to go to any of files.
new_file
Another text.
end
How using regex can I create two files with the following content:
file1
new_file
Some string.
end
file2
new_file
Another text.
end
How can I get information which is between keywords 'new_file' and 'end' to write it to the file?
If your files are not that large, you can read them in as a string, (use File.read(file_name)), and then run the following regex:
file_contents.scan(/^new_file$.*?^end$/m).select { |block| WRITE_TO_FILE_CODE_HERE }
See the regex demo
The ^new_file$.*?^end$ regex matches new_file that is a whole line content, then 0+ any characters as few as possible (incl. a newline as /m modifier is used), and then end (a whole line).
Else, you may adapt this answer here as
printing = false
File.open(my_file).each_line do |line|
printing = true if line =~ /^new_file$/
puts line if printing
printing = false if line =~ /^end$/
end
Open the file when the starting line is found, write to it where puts line is in the example above, and close when printing false occurs.
You can also read the file chunk by chunk by changing what constitutes a "line" in ruby:
File.open("file1.txt", "w") do |file1|
File.open("file2.txt", "w") do |file2|
enum = IO.foreach("old_file.txt", sep="\n\n")
file1.puts enum.next.strip
enum.next #discard
file2.puts enum.next.strip
end #automatically closes file2
end #automatically closes file1
By designating the separator as "\n\n" ruby will read all the characters up to and including two consecutive newlines--and return that as a "line".
If that kind of format is fixed, then you may try this (new_file\n.*\nend)
I have several files of this type:
File-1 (vip)-eojUBB_8V_4.mp4
File-2 (vip)-Ek2iyeeL1Vc.mp4
File-3 (vip)-Gh8F6OJa0gU.mp4
File-4 (vip)-SvL_aZt3zyU.mp4
and wanna rename file to:
File-1.mp4
File-2.mp4
Names "File1" and "File2" are just a example. Actually files have a different names but with "(vip)-smthing.mp4" in the end of filename.
I wrote the script:
#!/usr/bin/env ruby
require 'fileutils'
list = %x(ls -1 | grep .mp4).split(",")
list.each do |i|
File.rename(i, i.gsub(/(vip)*.mp4/, ".mp4"))
end
but can't understand, what pattern I need to write inside gsub.
Bash example work's fine, but i need to write it on Ruby.
ls -1 | sed 's/-[^-]\+\././'
#!/usr/bin/env ruby
require 'fileutils'
list = Dir.glob('*.mp4')
list.each do |src|
if src =~ /^(File\d+)/
dst = "#{$1}.mp4"
puts "renaming '#{src}' to '#{dst}'"
File.rename(src, dst)
end
end
Output:
$ ls
File1 (vip)-dHsq8aF2P0U.mp4 File2 (vip)-asdfsad.mp4 foo.rb
$ ruby foo.rb
renaming 'File1 (vip)-dHsq8aF2P0U.mp4' to 'File1.mp4'
renaming 'File2 (vip)-asdfsad.mp4' to 'File2.mp4'
$ ls
File1.mp4 File2.mp4 foo.rb
The answer is:
#!/usr/bin/env ruby
require 'fileutils'
list = %x(ls -1 | grep .mp4).split(",")
list.each do |i|
puts i.gsub(/ \(vip\)-\S+\./, ".")
end
Thanks to Philip Hallstrom and http://rubular.com/
I want to do with ARGF like this.
# file.rb
if ARGF.???
puts ARGF.read
else
puts "no redirect."
end
$ echo "Hello world" | ruby file.rb
Hello world
$ ruby file.rb
no redirect.
I need to do without waiting user input. I tried eof? or closed? doesn't help. Any ideas?
NOTE I was misunderstood ARGF. please see comments below.
Basically you'd examine #filename. One way to do this is:
if ARGF.filename != "-"
puts ARGF.read
else
puts "no redirect."
end
And this is the more complete form:
#!/usr/bin/env ruby
if ARGF.filename != "-" or (not STDIN.tty? and not STDIN.closed?)
puts ARGF.read
else
puts "No redirect."
end
Another:
#!/usr/bin/env ruby
if not STDIN.tty? and not STDIN.closed?
puts STDIN.read
else
puts "No redirect."
end
There might be a better way, but for me I needed to read the contents of a files being passed as arguments as well as having a files contents redirected to stdin.
my_executable
#!/usr/bin/env ruby
puts ARGF.pos.zero?
Then
$ my_executable file1.txt # passed as argument
#=> true
$ my_executable < file1.txt # redirected to stdin
#=> true
$ my_executable
#=> false
So I took all three currently suggested solutions:
p (not STDIN.tty? and not STDIN.closed?)
p ARGF.filename
p ARGF.pos
and saw that none of them actually works:
$ ruby temp.rb
false
"-"
36471287
$ ruby temp.rb temp.rb
false
"temp.rb"
0
$ echo 123 | ruby temp.rb
true
"-"
temp.rb:3:in `pos': Illegal seek # rb_io_tell - <STDIN> (Errno::ESPIPE)
from temp.rb:3:in `<main>'
because to assume the ability to call the ARGF.read you want to get false/true/true.
So I suppose you have to combine them:
!STDIN.tty? && !STDIN.closed? || ARGF.filename != ?-
I am new to Ruby. I have used shell in the past. I am converting a shell program to ruby. I have the following command
cmd="cat -n " + infile + " | grep '127.0.0.1 '" + site
f = %x[#{cmd}]
The shell cat command returns the line I am looking for and the line number. I would like to be able to do something similar in ruby without using shell. May need to port this program to windows. I can use the grep function in ruby but how do I return the line number without having to loop through a million lines in a file. Thanks.
Here's a little ruby function that'll do what you're asking for. You do have to loop through each line, but grep was doing that too - you just didn't have to do it yourself. Fortunately, ruby makes looping easy:
def mygrep(filename, regex)
result = []
File.open(filename) do |f|
f.each_with_index do |l, i|
result << [i, l] if regex =~ l
end
end
return result
end
Cheers!