Skip to content

Commit 96b8442

Browse files
updates for version 2.0
1 parent aec1868 commit 96b8442

40 files changed

+101994
-1518
lines changed

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 Sundeep Agarwal
3+
Copyright (c) 2023 Sundeep Agarwal
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

+32-33
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,36 @@
1-
# GNU AWK
1+
# CLI text processing with GNU awk
22

3-
Example based guide to mastering GNU awk.
3+
Example based guide to mastering GNU awk. Visit https://youtu.be/KIa_EaYwGDI for a short video about the book.
44

5-
<p align="center">
6-
<img src="./images/gawk.png" width="320px" height="400px" />
7-
</p>
5+
<p align="center"><img src="./images/gawk_ls.png" alt="CLI text processing with GNU awk ebook cover image" /></p>
86

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)
7+
The book also includes exercises to test your understanding, which are presented together as a single file in this repo [Exercises.md](./exercises/Exercises.md).
108

119
For solutions to the exercises, see [Exercise_solutions.md](./exercises/Exercise_solutions.md).
1210

11+
You can also use [this interactive TUI app](https://github.com/learnbyexample/TUI-apps/blob/main/AwkExercises) to practice some of the exercises from the book.
12+
1313
See [Version_changes.md](./Version_changes.md) to keep track of changes made to the book.
1414

1515
<br>
1616

1717
# E-book
1818

19-
You can purchase the pdf/epub versions of the book using these links:
20-
21-
* https://learnbyexample.gumroad.com/l/gnu_awk
22-
* https://leanpub.com/gnu_awk
23-
24-
You can also get the book as part of these bundles:
25-
26-
* **Magical one-liners** bundle from https://learnbyexample.gumroad.com/l/oneliners or https://leanpub.com/b/oneliners
27-
* **Awesome Regex** bundle from https://learnbyexample.gumroad.com/l/regex or https://leanpub.com/b/regex
28-
* **All books bundle** bundle from https://learnbyexample.gumroad.com/l/all-books
29-
* Includes all my programming books
30-
31-
See https://learnbyexample.github.io/books/ for list of other books
19+
* You can purchase the pdf/epub versions of the book using these links:
20+
* https://learnbyexample.gumroad.com/l/gnu_awk
21+
* https://leanpub.com/gnu_awk
22+
* You can also get the book as part of these bundles:
23+
* **All books bundle** bundle from https://learnbyexample.gumroad.com/l/all-books
24+
* Includes all my programming books
25+
* **Magical one-liners** bundle from https://learnbyexample.gumroad.com/l/oneliners or https://leanpub.com/b/oneliners
26+
* **Awesome Regex** bundle from https://learnbyexample.gumroad.com/l/regex or https://leanpub.com/b/regex
27+
* See https://learnbyexample.github.io/books/ for a list of other books
3228

33-
For a preview of the book, see [sample chapters](https://github.com/learnbyexample/learn_gnuawk/blob/master/sample_chapters/gnu_awk_sample.pdf)
29+
For a preview of the book, see [sample chapters](./sample_chapters/gnu_awk_sample.pdf).
3430

35-
The book can also be [viewed as a single markdown file in this repo](./gnu_awk.md). See my blogpost on [generating pdf from markdown using pandoc](https://learnbyexample.github.io/tutorial/ebook-generation/customizing-pandoc/) if you are interested in the ebook creation process.
31+
The book can also be [viewed as a single markdown file in this repo](./gnu_awk.md). See my blogpost on [generating pdfs from markdown using pandoc](https://learnbyexample.github.io/customizing-pandoc/) if you are interested in the ebook creation process.
3632

37-
For web version of the book, visit https://learnbyexample.github.io/learn_gnuawk/
33+
For the web version of the book, visit https://learnbyexample.github.io/learn_gnuawk/
3834

3935
<br>
4036

@@ -52,15 +48,17 @@ For web version of the book, visit https://learnbyexample.github.io/learn_gnuawk
5248
5349
<br>
5450

55-
# Feedback
51+
# Feedback and Contributing
5652

57-
[Open an issue](https://github.com/learnbyexample/learn_gnuawk/issues) if you spot any typo/errors.
53+
⚠️ ⚠️ Please DO NOT submit pull requests. Main reason being any modification requires changes in multiple places.
5854

59-
:warning: :warning: Please DO NOT submit pull requests. Main reason being any modification requires changes in multiple places.
55+
I would highly appreciate it if you'd let me know how you felt about this book. It could be anything from a simple thank you, pointing out a typo, mistakes in code snippets, which aspects of the book worked for you (or didn't!) and so on. Reader feedback is essential and especially so for self-published authors.
6056

61-
I'd also highly appreciate your feedback about the book.
57+
You can reach me via:
6258

63-
Twitter: https://twitter.com/learn_byexample
59+
* Issue Manager: [https://github.com/learnbyexample/learn_gnuawk/issues](https://github.com/learnbyexample/learn_gnuawk/issues)
60+
* E-mail: `echo 'bGVhcm5ieWV4YW1wbGUubmV0QGdtYWlsLmNvbQo=' | base64 --decode`
61+
* Twitter: [https://twitter.com/learn_byexample](https://twitter.com/learn_byexample)
6462

6563
<br>
6664

@@ -89,13 +87,14 @@ Twitter: https://twitter.com/learn_byexample
8987
# Acknowledgements
9088

9189
* [GNU awk documentation](https://www.gnu.org/software/gawk/manual/) — manual and examples
92-
* [stackoverflow](https://stackoverflow.com/) and [unix.stackexchange](https://unix.stackexchange.com/) — for getting answers to pertinent questions on `bash`, `awk` and other commands
90+
* [stackoverflow](https://stackoverflow.com/) and [unix.stackexchange](https://unix.stackexchange.com/) — for getting answers to pertinent questions on `awk` and related commands
9391
* [tex.stackexchange](https://tex.stackexchange.com/) — for help on [pandoc](https://github.com/jgm/pandoc/) and `tex` related questions
94-
* [LibreOffice Draw](https://www.libreoffice.org/discover/draw/) — cover image
95-
* [pngquant](https://pngquant.org/) and [svgcleaner](https://github.com/RazrFalcon/svgcleaner) for optimizing images
96-
* [softwareengineering.stackexchange](https://softwareengineering.stackexchange.com/questions/39/whats-your-favourite-quote-about-programming) and [skolakoda](https://skolakoda.org/programming-quotes) for programming quotes
92+
* [/r/commandline/](https://old.reddit.com/r/commandline), [/r/linux4noobs/](https://old.reddit.com/r/linux4noobs/), [/r/linuxquestions/](https://old.reddit.com/r/linuxquestions/) and [/r/linux/](https://old.reddit.com/r/linux/) — helpful forums
93+
* [canva](https://www.canva.com/) — cover image
94+
* [oxipng](https://github.com/shssoichiro/oxipng), [pngquant](https://pngquant.org/) and [svgcleaner](https://github.com/RazrFalcon/svgcleaner) — optimizing images
9795
* [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
9896
* [arifmahmudrana](https://github.com/arifmahmudrana) for spotting an ambiguous explanation
97+
* [Pound-Hash](https://github.com/Pound-Hash) for critical feedback
9998
* [mdBook](https://github.com/rust-lang/mdBook) — for web version of the book
10099
* [mdBook-pagetoc](https://github.com/JorelAli/mdBook-pagetoc) — for adding table of contents for each chapter
101100
* [minify-html](https://github.com/wilsonzlin/minify-html) — for minifying html files
@@ -106,7 +105,7 @@ Special thanks to all my friends and online acquaintances for their help, suppor
106105

107106
# License
108107

109-
The book is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-nc-sa/4.0/)
108+
The book is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-nc-sa/4.0/).
110109

111-
The code snippets are licensed under MIT, see [LICENSE](./LICENSE) file
110+
The code snippets are licensed under MIT, see [LICENSE](./LICENSE) file.
112111

Version_changes.md

+14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
<br>
22

3+
### 2.0
4+
5+
* Command version updated to **GNU awk 5.2.2**
6+
* Many more exercises added, and you can practice some of them using this [interactive TUI app](https://github.com/learnbyexample/TUI-apps/blob/main/AwkExercises)
7+
* Long sections split into smaller ones
8+
* In general, many of the examples, exercises, solutions, descriptions and external links were updated/corrected
9+
* Updated Acknowledgements section
10+
* Code snippets related to info/warning sections will now appear as a single block
11+
* Book title changed to **CLI text processing with GNU awk**
12+
* New cover image
13+
* Images centered for EPUB format
14+
15+
<br>
16+
317
### 1.4
418

519
* Added example for `NF` value when input line doesn't contain the input field separator or if it is empty.

code_snippets/Builtin_functions.sh

+4-4
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,17 @@ echo 'abcdefghij' | awk -v FS= '{print $3, $5}'
7474

7575
## match
7676

77-
s='051 035 154 12 26 98234'
77+
s='051 035 154 12 26 98234 3'
7878

7979
echo "$s" | awk 'match($0, /[0-9]{4,}/){print substr($0, RSTART, RLENGTH)}'
8080

8181
echo "$s" | awk 'match($0, /0*[1-9][0-9]{2,}/, m){print m[0]}'
8282

83-
echo 'foo=42, baz=314' | awk 'match($0, /baz=([0-9]+)/, m){print m[0]}'
83+
echo 'apple=42, fig=314' | awk 'match($0, /fig=([0-9]+)/, m){print m[0]}'
8484

85-
echo 'foo=42, baz=314' | awk 'match($0, /baz=([0-9]+)/, m){print m[1]}'
85+
echo 'apple=42, fig=314' | awk 'match($0, /fig=([0-9]+)/, m){print m[1]}'
8686

87-
s='42 foo-5, baz3; x-83, y-20: f12'
87+
s='42 apple-5, fig3; x-83, y-20: f12'
8888

8989
echo "$s" | awk '{ while( match($0, /([0-9]+),/, m) ){print m[1];
9090
$0=substr($0, RSTART+RLENGTH)} }'

code_snippets/Control_Structures.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ echo 'titillate' | awk '{do{print} while(gsub(/til/, ""))}'
2828

2929
## next
3030

31-
awk '/\<par/{print "%% " $0; next} {print /s/ ? "X" : "Y"}' word_anchors.txt
31+
awk '/\<par/{print "%% " $0; next} {print /s/ ? "X" : "Y"}' anchors.txt
3232

3333
## exit
3434

3535
seq 3542 4623452 | awk 'NR==2452{print; exit}'
3636

3737
echo $?
3838

39-
awk '/^br/{print "Invalid input"; exit 1}' table.txt
39+
awk '/^br/{print "invalid data"; exit 1}' table.txt
4040

4141
echo $?
4242

code_snippets/Field_separators.sh

+14-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ echo ' a b c ' | awk -F' ' '{print NF}'
6666

6767
echo ' a b c ' | awk -F'[ ]' '{print NF}'
6868

69-
echo 'RECONSTRUCTED' | awk -F'[aeiou]+' -v IGNORECASE=1 '{print $1}'
69+
echo 'RECONSTRUCTED' | awk -F'[aeiou]+' -v IGNORECASE=1 '{print $NF}'
7070

7171
echo 'RECONSTRUCTED' | awk -F'e' -v IGNORECASE=1 '{print $1}'
7272

@@ -92,6 +92,12 @@ echo 'Sample123string42with777numbers' | awk -F'[0-9]+' -v OFS=, '1'
9292

9393
echo 'Sample123string42with777numbers' | awk -F'[0-9]+' -v OFS=, '{$1=$1} 1'
9494

95+
echo -v{,O}FS=:
96+
97+
echo 'goal:amazing:whistle:kwality' | awk -v{,O}FS=: '{$2 = 42} 1'
98+
99+
echo 'goal:amazing:whistle:kwality' | awk '{$2 = 42} 1' {,O}FS=:
100+
95101
## Manipulating NF
96102

97103
echo 'goal:amazing:whistle:kwality' | awk -F: -v OFS=, '{NF=2} 1'
@@ -108,7 +114,13 @@ s='Sample123string42with777numbers'
108114

109115
echo "$s" | awk -v FPAT='[0-9]+' '{print $2}'
110116

111-
echo "$s" | awk -v FPAT='[a-zA-Z]+' -v OFS=, '{$1=$1} 1'
117+
s='coat Bin food tar12 best Apple fig_42'
118+
119+
echo "$s" | awk -v FPAT='\\<[a-z0-9]+\\>' -v OFS=, '{$1=$1} 1'
120+
121+
s='items: "apple" and "mango"'
122+
123+
echo "$s" | awk -v FPAT='"[^"]+"' '{print $1}'
112124

113125
s='eagle,"fox,42",bee,frog'
114126

code_snippets/Gotchas_and_Tips.sh

+11-9
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ awk -v word="cake" '$2==word' table.txt
66

77
awk -v field=2 '{print $field}' table.txt
88

9-
## Dos style line endings
9+
## DOS style line endings
1010

1111
printf 'mat dog\n123 789\n' | awk '{print $2, $1}'
1212

@@ -36,7 +36,7 @@ echo 'hi log_42 12b' | awk '{gsub(/\</, ":")} 1'
3636

3737
echo 'hi log_42 12b' | awk '{gsub(/\>/, ":")} 1'
3838

39-
## Relying on default initial value
39+
## Relying on the default initial value
4040

4141
awk '{sum += $NF} END{print sum}' table.txt
4242

@@ -46,7 +46,7 @@ awk '{sum += $NF} ENDFILE{print FILENAME ":" sum}' table.txt marks.txt
4646

4747
awk '{sum += $NF} ENDFILE{print FILENAME ":" sum; sum=0}' table.txt marks.txt
4848

49-
## Code in replacement section
49+
## Code in the replacement section
5050

5151
awk '{sub(/^(br|ye)/, ++c ") &")} 1' table.txt
5252

@@ -64,6 +64,8 @@ awk '{sum += $1} END{print sum}' /dev/null
6464

6565
awk '{sum += $1} END{print +sum}' /dev/null
6666

67+
## Locale based numbers
68+
6769
echo '3.14' | awk '{$0++} 1'
6870

6971
echo '3,14' | awk '{$0++} 1'
@@ -90,21 +92,21 @@ awk 'NF>2{print $(NF-2)}' varying.txt
9092

9193
## Faster execution
9294

93-
time awk '/^([a-d][r-z]){3}$/' /usr/share/dict/words > f1
95+
time awk '/^([a-d][r-z]){3}$/' words.txt > f1
9496

95-
time LC_ALL=C awk '/^([a-d][r-z]){3}$/' /usr/share/dict/words > f2
97+
time LC_ALL=C awk '/^([a-d][r-z]){3}$/' words.txt > f2
9698

97-
time mawk '/^[a-d][r-z][a-d][r-z][a-d][r-z]$/' /usr/share/dict/words > f3
99+
time mawk '/^[a-d][r-z][a-d][r-z][a-d][r-z]$/' words.txt > f3
98100

99101
diff -s f1 f2
100102

101103
diff -s f2 f3
102104

103105
rm f[123]
104106

105-
time awk -F'a' 'NF==4{cnt++} END{print +cnt}' /usr/share/dict/words
107+
time awk -F'a' 'NF==4{cnt++} END{print +cnt}' words.txt
106108

107-
time LC_ALL=C awk -F'a' 'NF==4{cnt++} END{print +cnt}' /usr/share/dict/words
109+
time LC_ALL=C awk -F'a' 'NF==4{cnt++} END{print +cnt}' words.txt
108110

109-
time mawk -F'a' 'NF==4{cnt++} END{print +cnt}' /usr/share/dict/words
111+
time mawk -F'a' 'NF==4{cnt++} END{print +cnt}' words.txt
110112

code_snippets/Installation_and_Documentation.sh

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
## Installation
22

3-
wget https://ftp.gnu.org/gnu/gawk/gawk-5.1.0.tar.xz
3+
wget https://ftp.gnu.org/gnu/gawk/gawk-5.2.2.tar.xz
44

5-
tar -Jxf gawk-5.1.0.tar.xz
5+
tar -Jxf gawk-5.2.2.tar.xz
66

7-
cd gawk-5.1.0/
7+
cd gawk-5.2.2/
88

99
./configure
1010

1111
make
1212

1313
sudo make install
1414

15-
type -a awk
16-
1715
awk --version | head -n1
1816

1917
## Documentation

code_snippets/Processing_multiple_records.sh

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
## Processing consecutive records
22

3-
awk 'p ~ /as/ && /not/{print p ORS $0} {p=$0}' programming_quotes.txt
3+
awk 'p ~ /he/ && /you/{print p ORS $0} {p=$0}' para.txt
44

5-
awk 'p ~ /as/ && /not/{print p} {p=$0}' programming_quotes.txt
5+
awk 'p ~ /he/ && /you/{print p} {p=$0}' para.txt
66

7-
awk 'p ~ /as/ && /not/; {p=$0}' programming_quotes.txt
7+
awk 'p ~ /he/ && /you/; {p=$0}' para.txt
88

99
## Context matching
1010

code_snippets/Record_separators.sh

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
## Input record separator
22

3-
printf 'this,is\na,sample' | awk -v RS=, '{print NR ")", $0}'
3+
printf 'this,is\na,sample,text' | awk -v RS=, '{print NR ")", $0}'
44

5-
s=' a\t\tb:1000\n\n\n\n123 7777:x y \n \n z '
5+
s=' a\t\tb:1000\n\n\t \n\n123 7777:x y \n \n z :apple banana cherry'
66

77
printf '%b' "$s" | awk -v RS=: -v OFS=, '{$1=$1} 1'
88

@@ -18,7 +18,7 @@ awk -v IGNORECASE=1 -v RS='[e]' 'NR==1' report.log
1818

1919
## Output record separator
2020

21-
printf 'foo\0bar\0' | awk -v RS='\0' -v ORS='.\n' '1'
21+
printf 'apple\0banana\0cherry\0' | awk -v RS='\0' -v ORS='.\n' '1'
2222

2323
cat msg.txt
2424

@@ -44,11 +44,11 @@ echo 'Sample123string42with777numbers' | awk -v RS='[0-9]+' '{print NR, RT}'
4444

4545
## Paragraph mode
4646

47-
cat programming_quotes.txt
47+
cat para.txt
4848

49-
awk -v RS= -v ORS='\n\n' '/you/' programming_quotes.txt
49+
awk -v RS= -v ORS='\n\n' '/do/' para.txt
5050

51-
awk -v RS= '/you/{print s $0; s="\n"}' programming_quotes.txt
51+
awk -v RS= '/do/{print s $0; s="\n"}' para.txt
5252

5353
s='\n\n\na\nb\n\n12\n34\n\nhi\nhello\n'
5454

@@ -66,7 +66,7 @@ s='a:b\nc:d\n\n1\n2\n3'
6666

6767
printf '%b' "$s" | awk -F: -v RS= -v ORS='\n---\n' '{$1=$1} 1'
6868

69-
printf '%b' "$s" | awk -F':+' -v RS= -v ORS='\n---\n' '{$1=$1} 1'
69+
printf '%b' "$s" | awk -F'[:]' -v RS= -v ORS='\n---\n' '{$1=$1} 1'
7070

7171
printf '%b' "$s" | awk -F: -v RS='\n\n+' -v ORS='\n---\n' '{$1=$1} 1'
7272

0 commit comments

Comments
 (0)