Why does gsub in Ruby one liner out hash refs? - ruby

Below you see my input file. Why does it output hash refs and not put the input without the ---?
$ cat a
---
Main:
aaah: Administrator
aacp: Administrator
a868: User
1585: User
5053: User
5423: User
/tmp$
$ ruby -pe 'gsub("---\n", '')' a
#<Enumerator:0x00005e335d1d08>#<Enumerator:0x00005e335d1b78>#<Enumerator:0x00005e335d1a38>#<Enumerator:0x00005e335d1920>#<Enumerator:0x00005e335d1808>#<Enumerator:0x00005e335d16f0>#<Enumerator:0x00005e335d15d8>#<Enumerator:0x00005e335d14c0>#<Enumerator:0x00005e335d13a8>#<Enumerator:0x00005e335d1290>

Your command needs the correct quotations.
Should look something like this:
$ ruby -pe 'gsub("---\n", "")' a
or
$ ruby -pe "gsub('---\n', '')" a

Related

How can I pipe output into another command?

I have a script located at /usr/local/bin/gq which is returned by the command whereis gq, well almost. What is actually returned is gq: /usr/local/bin/gq. But the following gives me just the filepath (with some white space)
whereis gq | cut -d ":" -f 2
What I’d like to do is be able to pipe that into cat, so I can see the contents. However the old pipe isn’t working. Any suggestions?
If you want to cat the contents of gq, then how about:
cat $(which gq)
The command which gq will result in /usr/local/bin/gq, and the cat command will act on that.

Shell: converting any number in a text file from decimal to hexadecimal

In a slightly different question from this other, I would like to convert any number in a text file from decimal to hexadecimal.
A number is here defined by a set of numeric characters together.
Example:
$ cat MyFile.txt
Hello,10,Good255Bye-boys01
Must become:
Hello,0A,GoodFFBye-boys01
Valid too:
Hello,A,GoodFFBye-boys1
Methods that allow (first case) to specify the character wide (to obtain 0A instead of A) are preferred.
I have tested grep to extract the numbers piped to bc to convert them:
( echo "obase=16" ; cat Line.txt |grep -o '[0-9]*') | bc
but this method shows only one (converted to hex) number each line, and removes the rest of the characters.
Since you're okay with using grep and bc in a pipe, it's clear that you don't want a solution in pure sh, but are happy to use external tools.
perl -pe 's/([0-9]+)/sprintf "%02X", $1/ge' myfile.txt
A Python solution (thanks to the suggestion from user 4ae1e1):
$ cat convert.py
#!/usr/bin/env python3
import fileinput
import re
for line in fileinput.input():
print(re.sub("\d+", lambda matchobj: "%X" % int(matchobj.group(0)), line), end="")
Example usage:
cat MyFile.txt | ./convert.py
or:
./convert.py MyFile.txt
dec2hex command will do the task.

How do you pipe shell output to ruby -e?

Say I was typing something in my terminal like:
ls | grep phrase
and after doing so I realize I want to delete all these files.
I want to use Ruby to do so, but can't quite figure out what to pass into it.
ls | grep phrase | ruby -e "what do I put in here to go through each line by line?"
Use this as a starting point:
ls ~ | ruby -ne 'print $_ if $_[/^D/]'
Which returns:
Desktop
Documents
Downloads
Dropbox
The -n flag means "loop over all incoming lines" and stores them in the "default" variable $_. We don't see that variable used much, partly as a knee-jerk reaction to Perl's overuse of it, but it has its useful moments in Rubydom.
These are the commonly used flags:
-e 'command' one line of script. Several -e's allowed. Omit [programfile]
-n assume 'while gets(); ... end' loop around your script
-p assume loop like -n but print line also like sed
ARGF will save your bacon.
ls | grep phrase | ruby -e "ARGF.read.each_line { |file| puts file }"
=> phrase_file
file_phrase
stuff_in_front_of_phrase
phrase_stuff_behind
ARGF is an array that stores whatever you passed into your (in this case command-line) script.
You can read more about ARGF here:
http://www.ruby-doc.org/core-1.9.3/ARGF.html
For more uses check out this talk on Ruby Forum:
http://www.ruby-forum.com/topic/85528

Prettify JSON data using Ruby on the terminal

I have earlier used Python for doing pretty output of JSON data like this:
python -mjson.tool input.json
I wanted to get similar output using Ruby. I am doing it like this:
ruby -rrubygems -e 'require "json"; ARGV.each { |f| print JSON.pretty_generate(JSON.load(File.open(f))) }' input.json
This is a lot for a small shell command. Can you suggest a better way?
You can shorten your script:
# ruby 1.9.2
ruby -rjson -e 'ARGF.each(nil) {|f| puts JSON.pretty_generate(JSON.parse(f)) }' file1 file2
# ruby 1.8.7
ruby -rubygems -e 'require "json"; ARGF.each(nil) {|f| puts JSON.pretty_generate(JSON.parse(f)) }' file1 file2
ARGF is a stream designed for use in scripts that process files given
as command-line arguments or passed in via STDIN.
I pass nil to ARGF#each method to split ARGF by files, not by lines (default behavior of #each).
There is a gem colorful_json which does exactly that.
You can also use the awesome_print gem.
Install it with: gem install awesome_print
Create a Bash function which will act as a shortcut
function jcurl { curl -s $* | ruby -rawesome_print -rjson -e 'ap JSON.parse(STDIN.read)'; }; export -f jcurl
Use your function to get pretty JSON in your Linux terminal:
jcurl http://127.0.0.1:3000/persons/1.json

Extracting words in quotes in shell script

I am making a shell script that will automate the install process of Arch Linux AUR packages. I need to list all dependencies of the package (to check if they are installed), they appear like this in install script:
depends=('sdl' 'libvorbis' 'openal')
The easiest way (or the only idea) that I could come up with is something like this:
grep "depends" PKGBUILD | awk -F"'" '{print $2 "\n" $4 "\n" $6;}'
But the dependency count varies from package to package. So, how I output the names in quotes if the word count is varying?
Thanks in advance,
-skazhy
If the depends is just one line, one thing you may try is to evaluate the line in bash itself... This will lead to an array called "depends" that holds all the values. Seems tricky, but not with dynamic languages:
depend_line=`grep depends $PKGBUILD`
eval "${depend_line}"
echo ${depend[0]} # Will print sdl in your example
You can avoid the security issues of using eval or sourcing a temporary file by using declare:
declare -a "$(grep "depends" PKGBUILD)"
This will create an array called "depends" containing "sdl", "libvorbis" and "openal" based on the example data.
Try this on for size:
grep "depends" PKGBUILD > /tmp/depends
. /tmp/depends
echo ${depends[#]}
Hey look, is that an array? Yes it is.
for d in "${depends[#]}" ; do
printf '"%s"' "$d"
done
Note: In a real script you'd want to be more careful with the naming of the temporary file.
You could do something like:
grep "depends" PKGBUILD | perl -e "while(<>){print \"\$1\\n\" while m/'.{-}'/g;}"
awk -F"'" '{for(i=2;i<=NF;i+=2) print($i)}'

Resources