Skip to content

Commit a2221eb

Browse files
files for version 1.0
1 parent 87b76d7 commit a2221eb

69 files changed

Lines changed: 6208 additions & 2 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,67 @@
1-
# learn_ruby_oneliners
2-
Example based guide for text processing with ruby from the command line
1+
# Ruby one-liners cookbook
2+
3+
Example based guide for text processing with `ruby` from the command line.
4+
5+
<p align="center">
6+
<img src="./images/ruby_oneliners.png" width="320px" height="400px" />
7+
</p>
8+
9+
The book also includes exercises to test your understanding, which is presented together as a single file in this repo - [Exercises.md](./exercises/Exercises.md)
10+
11+
For solutions to the exercises, see [Exercise_solutions.md](./exercises/Exercise_solutions.md).
12+
13+
See [Version_changes.md](./Version_changes.md) to keep track of changes made to the book.
14+
15+
<br>
16+
17+
# E-book
18+
19+
TODO
20+
21+
<br>
22+
23+
# Feedback
24+
25+
Please open an issue if you spot any typo/errors.
26+
27+
I'd also highly appreciate your feedback about the book.
28+
29+
Twitter: https://twitter.com/learn_byexample
30+
31+
<br>
32+
33+
# Table of Contents
34+
35+
1) Preface
36+
2) One-liner introduction
37+
3) Line processing
38+
4) Field separators
39+
5) Record separators
40+
6) Multiple file input
41+
7) Processing multiple records
42+
8) Two file processing
43+
9) Dealing with duplicates
44+
10) Processing structured data
45+
46+
<br>
47+
48+
# Acknowledgements
49+
50+
* [ruby-lang documentation](https://www.ruby-lang.org/en/documentation/) — manuals and tutorials
51+
* [/r/ruby/](https://www.reddit.com/r/ruby/) — helpful forum for beginners and experienced programmers alike
52+
* [stackoverflow](https://stackoverflow.com/) — for getting answers to pertinent questions on Ruby, one-liners, etc
53+
* [tex.stackexchange](https://tex.stackexchange.com/) — for help on `pandoc` and `tex` related questions
54+
* [LibreOffice Draw](https://www.libreoffice.org/discover/draw/) — cover image
55+
* [Warning](https://commons.wikimedia.org/wiki/File:Warning_icon.svg) and [Info](https://commons.wikimedia.org/wiki/File:Info_icon_002.svg) icons by [Amada44](https://commons.wikimedia.org/wiki/User:Amada44) under public domain
56+
* [softwareengineering.stackexchange](https://softwareengineering.stackexchange.com/questions/39/whats-your-favourite-quote-about-programming) and [skolakoda](https://skolakoda.org/programming-quotes) for programming quotes
57+
58+
A heartfelt thanks to all my readers. Your valuable support has significantly eased my financial concerns and allows me to continue writing books.
59+
60+
<br>
61+
62+
# License
63+
64+
The book is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-nc-sa/4.0/)
65+
66+
The code snippets are licensed under MIT, see [LICENSE](./LICENSE) file
67+

Version_changes.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<br>
2+
3+
### 1.0
4+
5+
* First version
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
## Whole line duplicates
2+
3+
cat purchases.txt
4+
5+
ruby -e 'puts readlines.uniq' purchases.txt
6+
7+
ruby -rset -ne 'BEGIN{s=Set.new}; print if s.add?($_)' purchases.txt
8+
9+
## Column wise duplicates
10+
11+
cat duplicates.txt
12+
13+
ruby -rset -F, -ane 'BEGIN{s=Set.new}; print if s.add?($F[-1])' duplicates.txt
14+
15+
ruby -rset -F, -ane 'BEGIN{s=Set.new};
16+
print if s.add?($F.values_at(0,2))' duplicates.txt
17+
18+
## Duplicate count
19+
20+
ruby -F, -ane 'BEGIN{h=Hash.new(0)};
21+
print if (h[$F[1]]+=1)==2' duplicates.txt
22+
23+
ruby -F, -ane 'BEGIN{h=Hash.new(0)};
24+
print if (h[$F[-1]]+=1)==3' duplicates.txt
25+
26+
tac duplicates.txt | ruby -rset -F, -ane 'BEGIN{s=Set.new};
27+
print if s.add?($F[-1])' | tac
28+
29+
ruby -F, -ane 'BEGIN{h=Hash.new(0)}; ARGV.size==1 ? h[$F[-1]]+=1 :
30+
h[$F[-1]]>1 && print' duplicates.txt duplicates.txt
31+
32+
ruby -F, -ane 'BEGIN{h=Hash.new(0)}; ARGV.size==1 ? h[$F[-1]]+=1 :
33+
h[$F[-1]]>2 && print' duplicates.txt duplicates.txt
34+
35+
ruby -F, -ane 'BEGIN{h=Hash.new(0)}; ARGV.size==1 ? h[$F[2]]+=1 :
36+
h[$F[2]]==1 && print' duplicates.txt duplicates.txt
37+

code_snippets/Field_separators.sh

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
## Default field separation
2+
3+
echo ' a b c ' | ruby -ane 'puts $F.size'
4+
5+
echo ' a b c ' | ruby -ane 'puts $F[0]'
6+
7+
echo ' a b c ' | ruby -ane 'puts $F[-1] + "."'
8+
9+
printf ' one \t\f\v two\t\r\tthree ' | ruby -ane 'puts $F.size'
10+
11+
printf ' one \t\f\v two\t\r\tthree ' | ruby -ane 'puts $F[1] + "."'
12+
13+
## Input field separator
14+
15+
echo 'goal:amazing:whistle:kwality' | ruby -F: -ane 'puts $F[0], $F[-1]'
16+
17+
echo 'one;two;three;four' | ruby -F';' -ane 'puts $F[2]'
18+
19+
echo 'load;err_msg--\ant,r2..not' | ruby -F'\W+' -ane 'puts $F[2]'
20+
21+
echo 'hi.bye.hello' | ruby -F'\.' -ane 'puts $F[1]'
22+
23+
printf 'COOL\nnice car\n' | ruby -F'(?i)[aeiou]' -ane 'puts $F.size - 1'
24+
25+
echo 'apple' | ruby -ne 'puts $_[0]'
26+
27+
ruby -e 'puts Encoding.default_external'
28+
29+
LC_ALL=C ruby -e 'puts Encoding.default_external'
30+
31+
echo 'fox:αλεπού' | ruby -ne 'puts $_[4..5]'
32+
33+
echo 'fox:αλεπού' | ruby -E UTF-8:UTF-8 -ne 'puts $_[4..5]'
34+
35+
echo 'cat dog' | ruby -ane 'puts "[#{$F[-1]}]"'
36+
37+
echo 'cat:dog' | ruby -F: -ane 'puts "[#{$F[-1]}]"'
38+
39+
printf 'cat:dog' | ruby -F: -ane 'puts "[#{$F[-1]}]"'
40+
41+
echo ' a b c ' | ruby -ane 'puts $F.size'
42+
43+
echo ':a:b:c:' | ruby -F: -ane 'puts $F.size'
44+
45+
echo 'cat:dog' | ruby -F: -lane 'puts "[#{$F[-1]}]"'
46+
47+
echo 'cat:dog' | ruby -F: -lane 'print "[#{$F[-1]}]"'
48+
49+
echo ':a:b:c:' | ruby -F: -lane 'puts $F.size'
50+
51+
echo ':a:b:c:' | ruby -lane 'puts $_.split(/:/, -1).size'
52+
53+
## Output field separator
54+
55+
ruby -lane 'BEGIN{$, = " "}; print $F[0], $F[2]' table.txt
56+
57+
ruby -W:no-deprecated -lane 'BEGIN{$, = " "}; print $F[0], $F[2]' table.txt
58+
59+
ruby -lane 'puts "#{$F[0]} #{$F[2]}"' table.txt
60+
61+
echo 'Sample123string42with777numbers' | ruby -F'\d+' -lane 'puts $F.join(",")'
62+
63+
s='goal:amazing:whistle:kwality'
64+
65+
echo "$s" | ruby -F: -lane 'puts $F.values_at(-1, 1, 0).join("-")'
66+
67+
echo "$s" | ruby -F: -lane '$F.append(42); puts $F * "::"'
68+
69+
## scan method
70+
71+
s='Sample123string42with777numbers'
72+
73+
echo "$s" | ruby -lne 'puts $_.scan(/\d+/)[1]'
74+
75+
echo "$s" | ruby -lne 'puts $_.scan(/[a-z]+/i) * ","'
76+
77+
s='eagle,"fox,42",bee,frog'
78+
79+
echo "$s" | ruby -F, -lane 'puts $F[1]'
80+
81+
echo "$s" | ruby -lne 'puts $_.scan(/"[^"]*"|[^,]+/)[1]'
82+
83+
## Fixed width processing
84+
85+
cat items.txt
86+
87+
ruby -ne 'puts $_.unpack("a8a4a6") * ","' items.txt
88+
89+
ruby -ne 'puts $_.unpack("a8a4a6")[1]' items.txt
90+
91+
ruby -ne 'puts $_.unpack("a5x3a3xa6") * ","' items.txt
92+
93+
printf 'banana\x0050\x00' | ruby -ne 'puts $_.unpack("Z*Z*") * ":"'
94+
95+
ruby -ne 'puts $_.unpack("a5x3a*") * ","' items.txt
96+
97+
echo 'b 123 good' | ruby -ne 'puts $_[2,3]'
98+
99+
echo 'b 123 good' | ruby -ne 'puts $_[6,4]'
100+
101+
echo 'b 123 good' | ruby -lpe '$_[2,3] = "gleam"'
102+
103+
## Assorted field processing methods
104+
105+
s='goal:amazing:42:whistle:kwality:3.14'
106+
107+
echo "$s" | ruby -F: -lane 'puts $F.grep(/i[nts]/) * ":"'
108+
109+
echo "$s" | ruby -F: -lane 'puts $F.grep_v(/\d/) * ":"'
110+
111+
s='goal:amazing:42:whistle:kwality:3.14'
112+
113+
echo "$s" | ruby -F: -lane 'puts $F.map(&:upcase) * ":"'
114+
115+
echo '23 756 -983 5' | ruby -ane 'puts $F.map {|n| n.to_i ** 2} * " "'
116+
117+
echo 'AaBbCc' | ruby -lne 'puts $_.chars.map(&:ord) * " "'
118+
119+
echo '3.14,17,6' | ruby -F, -ane 'puts $F.map(&:to_f).sum'
120+
121+
s='hour hand band mat heated pineapple'
122+
123+
echo "$s" | ruby -ane 'puts $F.filter {|w| w[0]!="h" && w.size<6}'
124+
125+
echo "$s" | ruby -ane 'puts $F.filter_map {|w|
126+
w.gsub(/[ae]/, "X") if w[0]=="h"}'
127+
128+
echo '3.14,17,6' | ruby -F, -lane 'puts $F.map(&:to_f).reduce(100, :+)'
129+
130+
echo '3.14,17,6' | ruby -F, -lane 'puts $F.map(&:to_f).reduce(:*)'
131+
132+
echo '3.14,17,6' | ruby -F, -lane 'puts $F.reduce(1) {|op,n| op*n.to_f}'
133+
134+
s='floor bat to dubious four'
135+
136+
echo "$s" | ruby -ane 'puts $F.sort * ":"'
137+
138+
echo "$s" | ruby -ane 'puts $F.sort_by(&:size) * ":"'
139+
140+
echo 'foobar' | ruby -lne 'puts $_.chars.sort.reverse * ""'
141+
142+
s='try a bad to good i teal by nice how'
143+
144+
echo "$s" | ruby -ane 'puts $F.sort { |a, b|
145+
[b.size, a] <=> [a.size, b] } * ":"'
146+
147+
s='3,b,a,3,c,d,1,d,c,2,2,2,3,1,b'
148+
149+
echo "$s" | ruby -F, -lane 'puts $F.uniq * ","'
150+
151+
cat marks.txt
152+
153+
ruby -ane 'idx = $F.each_index.sort {|i,j| $F[j] <=> $F[i]} if $.==1;
154+
puts $F.values_at(*idx) * "\t"' marks.txt
155+
156+
s='floor bat to dubious four'
157+
158+
echo "$s" | ruby -ane 'puts $F.shuffle * ":"'
159+
160+
echo 'foobar' | ruby -lne 'print $_.chars.shuffle * ""'
161+
162+
s='hour hand band mat heated pineapple'
163+
164+
echo "$s" | ruby -ane 'puts $F.sample'
165+
166+
echo "$s" | ruby -ane 'puts $F.sample(2)'
167+

0 commit comments

Comments
 (0)