As I think many people know, Ruby was created under the influence of Perl, so there is nothing surprising in the fact that Ruby can replace Perl in its niche of "practical data extraction and reporting." In this small post we will discuss the use of ruby for fine text processing in the console.
We remember two designs:
... | ruby -lne <CODE>
ruby -lne <CODE> file1, file2, ...
In the first case, the input data will be the output of the previous command, and in the second - the concatenation of the contents of the files.
CODE will be executed for each line of input data that will be written to the $_
variable. Important : the lines will be without the terminating \n
(the -l
flag is responsible for this).
Reflected cat
:
ruby -lne 'puts $_.reverse' file-to-show.txt
Display only the first 10 characters of the file name in the current directory:
ls | ruby -lne 'puts $_[0..9]'
Ruby has many predefined variables, many of which you and I may not even know. Among them are migrated from Perl, for example, $_
and $<
(in fact, in Perl there is no such variable, but there is a construction of an input operator <>
, reading from / stdin files and setting $_
).
A list of them can be found here .
As part of the topic of the post I advise you to pay attention to the above $_
and $<
, and in addition to them on: $~
, $1
, $stdin
, ARGV
, $stdout
, STDIN
and STDOUT
.
Perhaps many used gets
to request keyboard input. However, not everyone knows that he is checking the contents of the ARGV
- arguments command line.
When ARGV
non-empty, our gets
considers that the list of files is listed there, takes the first one and tries to read the line from there.
Take the script:
# myscript.rb puts gets
And run it using ruby myscript.rb
. As expected, the program is waiting for our input.
Now run it like this:
ruby myscript.rb no-such-file
An error will occur: the file "no-such-file" does not exist. And now change the script:
# myscript.rb ARGV.pop puts gets
Now the interpreter is waiting for our input again, because With the help of pop, we threw out our "no-such-file".
This is what my one-liner template looks like:
ruby -lne <CODE> [file1, file2, ...]
(often without -l
)
Description of the used and some potentially useful options:
-e <CODE>
- forces the interpreter not to try to search the script among the arguments and execute CODE
.-n
- wraps the script (or the code passed by -e
) into a while gets
. The gets
method implicitly sets the return value of the $_
variable (hello, Perl!), Which we should use. Important: the string will end \n
.-l
- for simplicity, we can assume that it simply removes the newline character \n
from $_
.-p
- works in the same way as -n
, but after each iteration it displays the contents of $_
. Those. implies that you will change it. For example: ls | ruby -pe '$_.upcase!'
ls | ruby -pe '$_.upcase!'
-C <DIR>
- changes the working directory.-a
(from auto-split) - used in conjunction with -n
or -p
and sets the variable $F
, equal to $_.split
.-F
- sets the standard separator for String#split
( $;
). In theory, it can be useful in conjunction with -a
. For example, you can handle simple .csvFor the first time, the cut
command prompted me to use ruby -e
. I had to use it a couple of times, and each time I had to open a manual that my tight head did not want to quickly understand.
In the end, I thought, "Yes, I do not know how to use cut
/ awk
/ sed
. But I know Ruby well, why can't I use it for small things?"
Actually, in the end, instead of memorizing a multitude of commands, it was enough for me to memorize only the construction obtained experimentally:
ruby -lne CODE
And that's all. All my problems with line processing text solved.
There is nothing innovative here, as far as I know, bearded system administrators have long been using perl in this vein. And among you, I bet, there are many people who know about it, but do not use it, although it would be worth it. Surely, the pythonists also have something similar.
PS Finally, here is an example of use:
I downloaded the season of the series, and there the files are ugly, like "s01e01 - super release by super-mega-macho.mkv", I want to rename them so that everything is beautiful in the media library. You are welcome:
ls | ruby -lne 'File.rename($_, "#{$_[0..5]}.mkv")'
Source: https://habr.com/ru/post/339544/
All Articles