├── LICENSE
├── README.md
├── Version_changes.md
├── cli_text_processing_coreutils.md
├── code_snippets
├── basename_and_dirname.sh
├── cat_and_tac.sh
├── comm.sh
├── csplit.sh
├── cut.sh
├── expand_and_unexpand.sh
├── fold_and_fmt.sh
├── head_and_tail.sh
├── join.sh
├── nl.sh
├── paste.sh
├── pr.sh
├── seq.sh
├── shuf.sh
├── sort.sh
├── split.sh
├── tr.sh
├── uniq.sh
└── wc.sh
├── example_files
├── all_sections.txt
├── body.txt
├── body_sep.txt
├── book_list.txt
├── code.py
├── colors_1.txt
├── colors_2.txt
├── dept.txt
├── e_notation.txt
├── file_size.txt
├── fruits.txt
├── greeting.txt
├── header_body.txt
├── info_fmt.txt
├── list_1.txt
├── list_2.txt
├── log.txt
├── marks.csv
├── mixed_fields.csv
├── mixed_numbers.txt
├── names.txt
├── nums.txt
├── purchases.txt
├── report_1.csv
├── report_2.csv
├── sample.txt
├── scores.csv
├── shopping.txt
├── shopping_feb.txt
├── shopping_jan.txt
├── timings.txt
└── versions.txt
├── exercises
├── Exercise_solutions.md
├── Exercises.md
├── all_sections.txt
├── blocks.txt
├── books.txt
├── colors.txt
├── duplicates.csv
├── f1.txt
├── fruits.txt
├── greeting.txt
├── ip.txt
├── items.txt
├── j1.txt
├── j2.txt
├── j3.txt
├── j4.txt
├── marks_1.csv
├── marks_2.csv
├── s1.txt
├── s2.txt
├── s3.txt
└── scores.csv
├── images
├── cli_coreutils_ls.png
├── info.svg
└── warning.svg
└── sample_chapters
└── cli_text_processing_coreutils_sample.pdf
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Sundeep Agarwal
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CLI text processing with GNU Coreutils
2 |
3 | You might be already aware of popular coreutils commands like `head`, `tail`, `tr`, `sort` and so on. This book will teach you more than twenty of such specialized text processing tools provided by the `GNU coreutils` package. Visit https://youtu.be/oCnJLu_PUbY for a short video about the book.
4 |
5 |
6 |
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).
8 |
9 | For solutions to the exercises, see [Exercise_solutions.md](./exercises/Exercise_solutions.md).
10 |
11 | See [Version_changes.md](./Version_changes.md) to keep track of changes made to the book.
12 |
13 |
14 |
15 | # E-book
16 |
17 | * You can purchase the pdf/epub versions of the book using these links:
18 | * https://learnbyexample.gumroad.com/l/cli_coreutils
19 | * https://leanpub.com/cli_coreutils
20 | * You can also get the book as part of these bundles:
21 | * **Linux CLI Text Processing** bundle from https://learnbyexample.gumroad.com/l/linux-cli-text-processing or https://leanpub.com/b/linux-cli-text-processing
22 | * **All books bundle** bundle from https://learnbyexample.gumroad.com/l/all-books
23 | * Includes all my programming books
24 | * See https://learnbyexample.github.io/books/ for a list of other books
25 |
26 | For a preview of the book, see [sample chapters](./sample_chapters/cli_text_processing_coreutils_sample.pdf).
27 |
28 | The book can also be [viewed as a single markdown file in this repo](./cli_text_processing_coreutils.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.
29 |
30 | For web version of the book, visit https://learnbyexample.github.io/cli_text_processing_coreutils/
31 |
32 |
33 |
34 | # Testimonials
35 |
36 | >In my opinion the book does a great job of quickly presenting examples of how commands can be used and then paired up to achieve new or interesting ways of manipulating data. Throughout the text there are little highlights offering tips on extra functionality or limitations of certain commands. For instance, when discussing the *shuf* command we're warned that *shuf* will not work with multiple files. However, we can merge multiple files together (using the *cat* command) and then pass them to *shuf*. These little gems of wisdom add a dimension to the book and will likely save the reader some time wondering why their scripts are not working as expected.
37 | >
38 | > — book review by Jesse Smith on [distrowatch.com](https://distrowatch.com/weekly.php?issue=20211206#book)
39 |
40 | >I discovered your books recently and they’re awesome, thank you! As a 20 year *nix they made me realize how much more there are to these rock solid and ancient tools, once you spend the time to actually learn the intricacies of them.
41 | >
42 | > — feedback on [reddit](https://old.reddit.com/r/commandline/comments/1byumd6/learn_gnu_coreutils_text_processing_tools_like/l2pk5bd/)
43 |
44 |
45 |
46 | # Feedback
47 |
48 | ⚠️ ⚠️ Please DO NOT submit pull requests. Main reason being any modification requires changes in multiple places.
49 |
50 | 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.
51 |
52 | You can reach me via:
53 |
54 | * Issue Manager: [https://github.com/learnbyexample/cli_text_processing_coreutils/issues](https://github.com/learnbyexample/cli_text_processing_coreutils/issues)
55 | * E-mail: `echo 'bGVhcm5ieWV4YW1wbGUubmV0QGdtYWlsLmNvbQo=' | base64 --decode`
56 | * Twitter: [https://twitter.com/learn_byexample](https://twitter.com/learn_byexample)
57 |
58 |
59 |
60 | # Table of Contents
61 |
62 | 1) Preface
63 | 2) Introduction
64 | 3) cat and tac
65 | 4) head and tail
66 | 5) tr
67 | 6) cut
68 | 7) seq
69 | 8) shuf
70 | 9) paste
71 | 10) pr
72 | 11) fold and fmt
73 | 12) sort
74 | 13) uniq
75 | 14) comm
76 | 15) join
77 | 16) nl
78 | 17) wc
79 | 18) split
80 | 19) csplit
81 | 20) expand and unexpand
82 | 21) basename and dirname
83 | 22) What next?
84 |
85 |
86 |
87 | # Acknowledgements
88 |
89 | * [GNU coreutils documentation](https://www.gnu.org/software/coreutils/manual/coreutils.html) — manual and examples
90 | * [/r/commandline/](https://old.reddit.com/r/commandline), [/r/linux4noobs/](https://old.reddit.com/r/linux4noobs/) and [/r/linux/](https://old.reddit.com/r/linux/) — helpful forums
91 | * [stackoverflow](https://stackoverflow.com/) and [unix.stackexchange](https://unix.stackexchange.com/) — for getting answers to pertinent questions on coreutils and related commands
92 | * [tex.stackexchange](https://tex.stackexchange.com/) — for help on [pandoc](https://github.com/jgm/pandoc/) and `tex` related questions
93 | * [canva](https://www.canva.com/) — cover image
94 | * [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
95 | * [oxipng](https://github.com/shssoichiro/oxipng), [pngquant](https://pngquant.org/) and [svgcleaner](https://github.com/RazrFalcon/svgcleaner) — optimizing images
96 | * [SpikePy](https://github.com/SpikePy) — for spotting an ambiguous explanation
97 | * [mdBook](https://github.com/rust-lang/mdBook) — for web version of the book
98 | * [mdBook-pagetoc](https://github.com/JorelAli/mdBook-pagetoc) — for adding table of contents for each page
99 | * [minify-html](https://github.com/wilsonzlin/minify-html) — for minifying html files
100 |
101 |
102 |
103 | # License
104 |
105 | The book is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-nc-sa/4.0/).
106 |
107 | The code snippets are licensed under MIT, see [LICENSE](./LICENSE) file.
108 |
109 |
--------------------------------------------------------------------------------
/Version_changes.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ### 2.0
4 |
5 | * `GNU coreutils` package version updated to **9.1**
6 | * Added 100+ exercises
7 | * In general, many of the examples, descriptions and external links were updated/corrected
8 | * Updated Acknowledgements section
9 | * Code snippets related to info/warning sections will now appear as a single block
10 | * Book title changed to **CLI text processing with GNU Coreutils**
11 | * New cover image
12 |
13 |
14 |
15 | ### 1.0
16 |
17 | * First version
18 |
19 |
--------------------------------------------------------------------------------
/code_snippets/basename_and_dirname.sh:
--------------------------------------------------------------------------------
1 | ## Extract filename from paths
2 |
3 | basename /home/learnbyexample/example_files/scores.csv
4 |
5 | basename 'path with spaces/report.log'
6 |
7 | basename /home/learnbyexample/example_files/
8 |
9 | basename filename.txt
10 |
11 | basename /
12 |
13 | ## Remove file extension
14 |
15 | basename -s'.csv' /home/learnbyexample/example_files/scores.csv
16 |
17 | basename -s'_2' final_report.txt_2
18 |
19 | basename -s'.tar.gz' /backups/jan_2021.tar.gz
20 |
21 | basename -s'.txt' purchases.txt.txt
22 |
23 | basename -s'report' /backups/report
24 |
25 | basename example_files/scores.csv .csv
26 |
27 | ## Remove filename from path
28 |
29 | dirname /home/learnbyexample/example_files/scores.csv
30 |
31 | dirname /home/learnbyexample/example_files/
32 |
33 | ## Multiple arguments
34 |
35 | basename -a /backups/jan_2021.tar.gz /home/learnbyexample/report.log
36 |
37 | basename -s'.txt' logs/purchases.txt logs/report.txt
38 |
39 | dirname /home/learnbyexample/example_files/scores.csv ../report/backups/
40 |
41 | ## Combining basename and dirname
42 |
43 | basename $(dirname /home/learnbyexample/example_files/scores.csv)
44 |
45 | ## NUL separator
46 |
47 | basename -zs'.txt' logs/purchases.txt logs/report.txt | cat -v
48 |
49 | basename -z logs/purchases.txt | cat -v
50 |
51 | dirname -z example_files/scores.csv ../report/backups/ | cat -v
52 |
53 |
--------------------------------------------------------------------------------
/code_snippets/cat_and_tac.sh:
--------------------------------------------------------------------------------
1 | ## Creating text files
2 |
3 | cat > greeting.txt
4 |
5 | cat greeting.txt
6 |
7 | cat << 'EOF' > fruits.txt
8 | banana
9 | papaya
10 | mango
11 | EOF
12 |
13 | cat fruits.txt
14 |
15 | tr 'a-z' 'A-Z' << 'end' > op.txt
16 | hi there
17 | have a nice day
18 | end
19 |
20 | cat op.txt
21 |
22 | ## Concatenate files
23 |
24 | cat greeting.txt fruits.txt nums.txt
25 |
26 | cat greeting.txt fruits.txt nums.txt > op.txt
27 |
28 | cat op.txt
29 |
30 | ## Accepting stdin data
31 |
32 | echo 'apple banana cherry' | cat
33 |
34 | echo 'apple banana cherry' | cat greeting.txt -
35 |
36 | printf 'Some\nNumbers' | cat - nums.txt
37 |
38 | ## Squeeze consecutive empty lines
39 |
40 | printf 'hello\n\n\nworld\n\nhave a nice day\n\n\n\n\n\napple\n'
41 |
42 | printf 'hello\n\n\nworld\n\nhave a nice day\n\n\n\n\n\napple\n' | cat -s
43 |
44 | ## Prefix line numbers
45 |
46 | cat -n greeting.txt fruits.txt nums.txt
47 |
48 | printf 'apple\n\nbanana\n\ncherry\n' | cat -n
49 |
50 | printf 'apple\n\nbanana\n\ncherry\n' | cat -b
51 |
52 | ## Viewing special characters
53 |
54 | printf 'mar\bt\nbike\rp\n'
55 |
56 | printf 'mar\bt\nbike\rp\n' | cat -v
57 |
58 | printf 'car\0jeep\0bus\0' | cat -v
59 |
60 | printf '1 2\t3\f4\v5\n' | cat -v
61 |
62 | printf 'good food\tnice dice\napple\tbanana\tcherry\n' | cat -T
63 |
64 | printf 'ice \nwater\n cool \n chill\n' | cat -E
65 |
66 | printf 'mar\bt\nbike\rp\n' | cat -e
67 |
68 | printf '1 2\t3\f4\v5\n' | cat -t
69 |
70 | printf '1 2\t3\f4\v5\n' | cat -A
71 |
72 | ## Useless use of cat
73 |
74 | cat greeting.txt | sed -E 's/\w+/\L\u&/g'
75 |
76 | sed -E 's/\w+/\L\u&/g' greeting.txt
77 |
78 | cat greeting.txt | tr 'a-z' 'A-Z'
79 |
80 | ' greeting.txt
26 |
27 | ## Starting number and step value
28 |
29 | nl -v10 greeting.txt
30 |
31 | nl -v-1 fruits.txt
32 |
33 | nl -w2 -s') ' -i2 greeting.txt fruits.txt nums.txt
34 |
35 | nl -w1 -s'. ' -v8 -i-1 greeting.txt fruits.txt
36 |
37 | ## Section wise numbering
38 |
39 | cat body.txt
40 |
41 | nl -w1 -s' ' body.txt
42 |
43 | cat header_body.txt
44 |
45 | nl -w1 -s' ' header_body.txt
46 |
47 | cat all_sections.txt
48 |
49 | nl -w1 -s' ' all_sections.txt
50 |
51 | nl -w1 -s' ' -ha -fa all_sections.txt
52 |
53 | nl -p -w1 -s' ' all_sections.txt
54 |
55 | nl -p -w1 -s' ' -ha -fa all_sections.txt
56 |
57 | cat body_sep.txt
58 |
59 | nl -w1 -s' ' -d'%=' body_sep.txt
60 |
61 | ## Section numbering criteria
62 |
63 | printf 'apple\n\nbanana\n\ncherry\n' | nl -w1 -s' ' -ba
64 |
65 | printf 'a\n\n\n\n\nb\n\nc' | nl -w1 -s' ' -ba -l2
66 |
67 | nl -w1 -s' ' -bp'^[ct]' purchases.txt
68 |
69 |
--------------------------------------------------------------------------------
/code_snippets/paste.sh:
--------------------------------------------------------------------------------
1 | ## Concatenating files column wise
2 |
3 | cat colors_1.txt
4 |
5 | cat colors_2.txt
6 |
7 | paste colors_1.txt colors_2.txt
8 |
9 | seq 4 | paste -d, - <(seq 6 9)
10 |
11 | paste -d'|' <(seq 3) <(seq 4 5) <(seq 6 8)
12 |
13 | paste -d '' <(seq 3) <(seq 6 8)
14 |
15 | ## Interleaving lines
16 |
17 | paste -d'\n' <(seq 11 13) <(seq 101 103)
18 |
19 | ## Multiple columns from single input
20 |
21 | seq 10 | paste -d, - -
22 |
23 | seq 10 | paste -d: - - - - -
24 |
25 | e
46 |
47 | paste -d' : - ' <(seq 3) e e <(seq 4 6) e e <(seq 7 9)
48 |
49 | ## Serialize
50 |
51 | n1.txt
142 |
143 | shuf -n1000000 -i1-999999999999 > n2.txt
144 |
145 | sort -n n1.txt > n1_sorted.txt
146 |
147 | sort -n n2.txt > n2_sorted.txt
148 |
149 | time sort -n n1.txt n2.txt > op1.txt
150 |
151 | time sort -mn n1_sorted.txt <(sort -n n2.txt) > op2.txt
152 |
153 | time sort -mn n1_sorted.txt n2_sorted.txt > op3.txt
154 |
155 | diff -sq op1.txt op2.txt
156 |
157 | diff -sq op1.txt op3.txt
158 |
159 | rm n{1,2}{,_sorted}.txt op{1..3}.txt
160 |
161 | ## NUL separator
162 |
163 | printf 'cherry\0apple\0banana' | sort -z | cat -v
164 |
165 |
--------------------------------------------------------------------------------
/code_snippets/split.sh:
--------------------------------------------------------------------------------
1 | ## Default split
2 |
3 | seq 10000 | split
4 |
5 | ls x*
6 |
7 | head -n1 xaa xab xae xaj
8 |
9 | rm x*
10 |
11 | ## Change number of lines
12 |
13 | split -l3 purchases.txt
14 |
15 | head x*
16 |
17 | ## Split by byte count
18 |
19 | split -b15 greeting.txt
20 |
21 | head x*
22 |
23 | cat x*
24 |
25 | split -C20 purchases.txt
26 |
27 | head x*
28 |
29 | wc -c x*
30 |
31 | printf 'apple\nbanana\n' | split -C4
32 |
33 | head x*
34 |
35 | cat x*
36 |
37 | ## Divide based on file size
38 |
39 | split -n2 purchases.txt
40 |
41 | head x*
42 |
43 | wc x*
44 |
45 | seq 6 | split -n2
46 |
47 | split -n1/2 greeting.txt
48 |
49 | split -nl/2 purchases.txt
50 |
51 | head x*
52 |
53 | split -nl/2/3 sample.txt
54 |
55 | ## Interleaved lines
56 |
57 | seq 5 | split -nr/2
58 |
59 | head x*
60 |
61 | split -nr/1/3 sample.txt
62 |
63 | ## Custom line separator
64 |
65 | printf 'apple\nbanana\n;mango\npapaya\n' | split -t';' -l1
66 |
67 | head x*
68 |
69 | ## Customize filenames
70 |
71 | split -l1 greeting.txt op_
72 |
73 | head op_*
74 |
75 | seq 10 | split -l1 -a1
76 |
77 | ls x*
78 |
79 | rm x*
80 |
81 | seq 10 | split -l1 -a3
82 |
83 | ls x*
84 |
85 | rm x*
86 |
87 | seq 100 | split -l1 -a1
88 |
89 | ls x*
90 |
91 | rm x*
92 |
93 | seq 10 | split -l1 -d
94 |
95 | ls x*
96 |
97 | rm x*
98 |
99 | seq 10 | split -l2 --numeric-suffixes=10
100 |
101 | ls x*
102 |
103 | seq 10 | split -l1 --hex-suffixes=8
104 |
105 | ls x*
106 |
107 | seq 10 | split -l2 -a1 --additional-suffix='.log'
108 |
109 | ls x*
110 |
111 | rm x*
112 |
113 | seq 10 | split -l2 -a1 -d --additional-suffix='.txt' - num_
114 |
115 | ls num_*
116 |
117 | ## Exclude empty files
118 |
119 | split -nl/3 greeting.txt
120 |
121 | head x*
122 |
123 | rm x*
124 |
125 | split -e -nl/3 greeting.txt
126 |
127 | head x*
128 |
129 | ## Process parts through another command
130 |
131 | split -l1 --filter='gzip > $FILE.gz' greeting.txt
132 |
133 | ls x*
134 |
135 | zcat xaa.gz
136 |
137 | zcat xab.gz
138 |
139 | cat body_sep.txt
140 |
141 | split -l3 --filter='tail -n +2 > $FILE' body_sep.txt
142 |
143 | head x*
144 |
145 |
--------------------------------------------------------------------------------
/code_snippets/tr.sh:
--------------------------------------------------------------------------------
1 | ## Transliteration
2 |
3 | echo 'leet speak' | tr 'lets' '1375'
4 |
5 | echo 'apple;banana;cherry' | tr ; :
6 |
7 | echo 'apple;banana;cherry' | tr ';' ':'
8 |
9 | echo 'HELLO WORLD' | tr 'A-Z' 'a-z'
10 |
11 | echo 'Hello World' | tr 'a-zA-Z' 'A-Za-z'
12 |
13 | echo 'Hello World' | tr 'a-zA-Z' 'n-za-mN-ZA-M'
14 |
15 | echo 'Uryyb Jbeyq' | tr 'a-zA-Z' 'n-za-mN-ZA-M'
16 |
17 | tr 'a-z' 'A-Z' ip.txt
60 |
61 | uniq ip.txt op.txt
62 |
63 | cat op.txt
64 |
65 | ## NUL separator
66 |
67 | printf 'cherry\0cherry\0cherry\0apple\0banana' | uniq -z | cat -v
68 |
69 |
--------------------------------------------------------------------------------
/code_snippets/wc.sh:
--------------------------------------------------------------------------------
1 | ## Line, word and byte counts
2 |
3 | cat greeting.txt
4 |
5 | wc greeting.txt
6 |
7 | ## Individual counts
8 |
9 | wc -l greeting.txt
10 |
11 | wc -w greeting.txt
12 |
13 | wc -c greeting.txt
14 |
15 | wc -wc greeting.txt
16 |
17 | printf 'hello' | wc -c
18 |
19 | printf 'hello' | wc -c -
20 |
21 | lines=$(wc -l y:
3 | print('hello')
4 | else:
5 | print('bye')
6 |
--------------------------------------------------------------------------------
/example_files/colors_1.txt:
--------------------------------------------------------------------------------
1 | Blue
2 | Brown
3 | Orange
4 | Purple
5 | Red
6 | Teal
7 | White
8 |
--------------------------------------------------------------------------------
/example_files/colors_2.txt:
--------------------------------------------------------------------------------
1 | Black
2 | Blue
3 | Green
4 | Orange
5 | Pink
6 | Red
7 | White
8 |
--------------------------------------------------------------------------------
/example_files/dept.txt:
--------------------------------------------------------------------------------
1 | CSE
2 | ECE
3 |
--------------------------------------------------------------------------------
/example_files/e_notation.txt:
--------------------------------------------------------------------------------
1 | +120
2 | -1.53
3 | 3.14e+4
4 | 42.1e-2
5 |
--------------------------------------------------------------------------------
/example_files/file_size.txt:
--------------------------------------------------------------------------------
1 | 104K power.log
2 | 316M projects
3 | 746K report.log
4 | 20K sample.txt
5 | 1.4G games
6 |
--------------------------------------------------------------------------------
/example_files/fruits.txt:
--------------------------------------------------------------------------------
1 | banana
2 | papaya
3 | mango
4 |
--------------------------------------------------------------------------------
/example_files/greeting.txt:
--------------------------------------------------------------------------------
1 | Hi there
2 | Have a nice day
3 |
--------------------------------------------------------------------------------
/example_files/header_body.txt:
--------------------------------------------------------------------------------
1 | \:\:\:
2 | Header
3 | teal
4 | \:\:
5 | Hi there
6 | How are you
7 | \:\:
8 | banana
9 | papaya
10 | mango
11 | \:\:\:
12 | Header
13 | green
14 |
--------------------------------------------------------------------------------
/example_files/info_fmt.txt:
--------------------------------------------------------------------------------
1 | fmt prefers breaking lines at the end of a sentence, and tries to avoid line breaks after the first word of a sentence or before the last word of a sentence. A sentence break is defined as either the end of a paragraph or a word ending in any of '.?!', followed by two spaces or end of line, ignoring any intervening parentheses or quotes. Like TeX, fmt reads entire "paragraphs" before choosing line breaks; the algorithm is a variant of that given by Donald E. Knuth and Michael F. Plass in "Breaking Paragraphs Into Lines", Software—Practice & Experience 11, 11 (November 1981), 1119–1184.
2 |
--------------------------------------------------------------------------------
/example_files/list_1.txt:
--------------------------------------------------------------------------------
1 | apple
2 | banana
3 | cherry
4 | cherry
5 | cherry
6 | cherry
7 |
--------------------------------------------------------------------------------
/example_files/list_2.txt:
--------------------------------------------------------------------------------
1 | cherry
2 | cherry
3 | mango
4 | papaya
5 |
--------------------------------------------------------------------------------
/example_files/log.txt:
--------------------------------------------------------------------------------
1 | --> warning 1
2 | a,b,c,d
3 | 42
4 | --> warning 2
5 | x,y,z
6 | --> warning 3
7 | 4,3,1
8 |
--------------------------------------------------------------------------------
/example_files/marks.csv:
--------------------------------------------------------------------------------
1 | ECE,Raj,53
2 | ECE,Joel,72
3 | EEE,Moi,68
4 | CSE,Surya,81
5 | EEE,Raj,88
6 | CSE,Moi,62
7 | EEE,Tia,72
8 | ECE,Om,92
9 | CSE,Amy,67
10 |
--------------------------------------------------------------------------------
/example_files/mixed_fields.csv:
--------------------------------------------------------------------------------
1 | 1,2,3,4
2 | hello
3 | a,b,c
4 |
--------------------------------------------------------------------------------
/example_files/mixed_numbers.txt:
--------------------------------------------------------------------------------
1 | 12,345
2 | 42
3 | 31.24
4 | -100
5 | 42
6 | 5678
7 |
--------------------------------------------------------------------------------
/example_files/names.txt:
--------------------------------------------------------------------------------
1 | Amy
2 | Raj
3 | Tia
4 |
--------------------------------------------------------------------------------
/example_files/nums.txt:
--------------------------------------------------------------------------------
1 | 3.14
2 | 42
3 | 1000
4 |
--------------------------------------------------------------------------------
/example_files/purchases.txt:
--------------------------------------------------------------------------------
1 | coffee
2 | tea
3 | washing powder
4 | coffee
5 | toothpaste
6 | tea
7 | soap
8 | tea
9 |
--------------------------------------------------------------------------------
/example_files/report_1.csv:
--------------------------------------------------------------------------------
1 | Name,Maths,Physics
2 | Amy,78,95
3 | Moi,88,75
4 | Raj,67,76
5 |
--------------------------------------------------------------------------------
/example_files/report_2.csv:
--------------------------------------------------------------------------------
1 | Name,Chemistry
2 | Amy,85
3 | Joel,78
4 | Raj,72
5 |
--------------------------------------------------------------------------------
/example_files/sample.txt:
--------------------------------------------------------------------------------
1 | 1) Hello World
2 | 2)
3 | 3) Hi there
4 | 4) How are you
5 | 5)
6 | 6) Just do-it
7 | 7) Believe it
8 | 8)
9 | 9) banana
10 | 10) papaya
11 | 11) mango
12 | 12)
13 | 13) Much ado about nothing
14 | 14) He he he
15 | 15) Adios amigo
16 |
--------------------------------------------------------------------------------
/example_files/scores.csv:
--------------------------------------------------------------------------------
1 | Name,Maths,Physics,Chemistry
2 | Ith,100,100,100
3 | Cy,97,98,95
4 | Lin,78,83,80
5 |
--------------------------------------------------------------------------------
/example_files/shopping.txt:
--------------------------------------------------------------------------------
1 | apple 50
2 | toys 5
3 | Pizza 2
4 | mango 25
5 | Banana 10
6 |
--------------------------------------------------------------------------------
/example_files/shopping_feb.txt:
--------------------------------------------------------------------------------
1 | banana 15
2 | fig 100
3 | pen 2
4 | soap 1
5 |
--------------------------------------------------------------------------------
/example_files/shopping_jan.txt:
--------------------------------------------------------------------------------
1 | apple 10
2 | banana 20
3 | soap 3
4 | tshirt 3
5 |
--------------------------------------------------------------------------------
/example_files/timings.txt:
--------------------------------------------------------------------------------
1 | 5m35.363s
2 | 3m20.058s
3 | 4m11.130s
4 | 3m42.833s
5 | 4m3.083s
6 |
--------------------------------------------------------------------------------
/example_files/versions.txt:
--------------------------------------------------------------------------------
1 | file2
2 | cmd5.2
3 | file10
4 | cmd1.6
5 | file5
6 | cmd5.10
7 |
--------------------------------------------------------------------------------
/exercises/Exercise_solutions.md:
--------------------------------------------------------------------------------
1 | # Exercise solutions
2 |
3 |
4 |
5 | # cat and tac
6 |
7 | **1)** The given sample data has empty lines at the start and end of the input. Also, there are multiple empty lines between the paragraphs. How would you get the output shown below?
8 |
9 | ```bash
10 | # note that there's an empty line at the end of the output
11 | $ printf '\n\n\ndragon\n\n\n\nunicorn\nbee\n\n\n' | cat -sb
12 |
13 | 1 dragon
14 |
15 | 2 unicorn
16 | 3 bee
17 |
18 | ```
19 |
20 | **2)** Pass appropriate arguments to the `cat` command to get the output shown below.
21 |
22 | ```bash
23 | $ cat greeting.txt
24 | Hi there
25 | Have a nice day
26 |
27 | $ echo '42 apples and 100 bananas' | cat - greeting.txt
28 | 42 apples and 100 bananas
29 | Hi there
30 | Have a nice day
31 | ```
32 |
33 | **3)** What does the `-v` option of the `cat` command do?
34 |
35 | Displays nonprinting characters using the caret notation.
36 |
37 | **4)** Which options of the `cat` command do the following stand in for?
38 |
39 | * `-e` option is equivalent to `-vE`
40 | * `-t` option is equivalent to `-vT`
41 | * `-A` option is equivalent to `-vET`
42 |
43 | **5)** Will the two commands shown below produce the same output? If not, why not?
44 |
45 | ```bash
46 | $ cat fruits.txt ip.txt | tac
47 |
48 | $ tac fruits.txt ip.txt
49 | ```
50 |
51 | No. The first command concatenates the input files before reversing the content linewise. With the second command, each file content will be reversed separately.
52 |
53 | **6)** Reverse the contents of `blocks.txt` file as shown below, considering `----` as the separator.
54 |
55 | ```bash
56 | $ cat blocks.txt
57 | ----
58 | apple--banana
59 | mango---fig
60 | ----
61 | 3.14
62 | -42
63 | 1000
64 | ----
65 | sky blue
66 | dark green
67 | ----
68 | hi hello
69 |
70 | $ tac -bs '----' blocks.txt
71 | ----
72 | hi hello
73 | ----
74 | sky blue
75 | dark green
76 | ----
77 | 3.14
78 | -42
79 | 1000
80 | ----
81 | apple--banana
82 | mango---fig
83 | ```
84 |
85 | **7)** For the `blocks.txt` file, write solutions to display only the last such group and last two groups.
86 |
87 | ```bash
88 | # can also use: tac -bs '----' blocks.txt | awk '/----/ && ++c==2{exit} 1'
89 | $ tac blocks.txt | sed '/----/q' | tac
90 | ----
91 | hi hello
92 |
93 | $ tac -bs '----' blocks.txt | awk '/----/ && ++c==3{exit} 1' | tac -bs '----'
94 | ----
95 | sky blue
96 | dark green
97 | ----
98 | hi hello
99 | ```
100 |
101 | **8)** Reverse the contents of `items.txt` as shown below. Consider digits at the start of lines as the separator.
102 |
103 | ```bash
104 | $ cat items.txt
105 | 1) fruits
106 | apple 5
107 | banana 10
108 | 2) colors
109 | green
110 | sky blue
111 | 3) magical beasts
112 | dragon 3
113 | unicorn 42
114 |
115 | $ tac -brs '^[0-9]' items.txt
116 | 3) magical beasts
117 | dragon 3
118 | unicorn 42
119 | 2) colors
120 | green
121 | sky blue
122 | 1) fruits
123 | apple 5
124 | banana 10
125 | ```
126 |
127 |
128 |
129 | # head and tail
130 |
131 | **1)** Use appropriate commands and shell features to get the output shown below.
132 |
133 | ```bash
134 | $ printf 'carpet\njeep\nbus\n'
135 | carpet
136 | jeep
137 | bus
138 |
139 | # use the above 'printf' command for input data
140 | $ c=$(printf 'carpet\njeep\nbus\n' | head -c3)
141 | $ echo "$c"
142 | car
143 | ```
144 |
145 | **2)** How would you display all the input lines except the first one?
146 |
147 | ```bash
148 | $ printf 'apple\nfig\ncarpet\njeep\nbus\n' | tail -n +2
149 | fig
150 | carpet
151 | jeep
152 | bus
153 | ```
154 |
155 | **3)** Which command would you use to get the output shown below?
156 |
157 | ```bash
158 | $ cat fruits.txt
159 | banana
160 | papaya
161 | mango
162 | $ cat blocks.txt
163 | ----
164 | apple--banana
165 | mango---fig
166 | ----
167 | 3.14
168 | -42
169 | 1000
170 | ----
171 | sky blue
172 | dark green
173 | ----
174 | hi hello
175 |
176 | $ head -n2 fruits.txt blocks.txt
177 | ==> fruits.txt <==
178 | banana
179 | papaya
180 |
181 | ==> blocks.txt <==
182 | ----
183 | apple--banana
184 | ```
185 |
186 | **4)** Use a combination of `head` and `tail` commands to get the 11th to 14th characters from the given input.
187 |
188 | ```bash
189 | # can also use: tail -c +11 | head -c4
190 | $ printf 'apple\nfig\ncarpet\njeep\nbus\n' | head -c14 | tail -c +11
191 | carp
192 | ```
193 |
194 | **5)** Extract the starting six bytes from the input files `ip.txt` and `fruits.txt`.
195 |
196 | ```bash
197 | $ head -q -c6 ip.txt fruits.txt
198 | it is banana
199 | ```
200 |
201 | **6)** Extract the last six bytes from the input files `fruits.txt` and `ip.txt`.
202 |
203 | ```bash
204 | $ tail -q -c6 fruits.txt ip.txt
205 | mango
206 | erish
207 | ```
208 |
209 | **7)** For the input file `ip.txt`, display except the last 5 lines.
210 |
211 | ```bash
212 | $ head -n -5 ip.txt
213 | it is a warm and cozy day
214 | listen to what I say
215 | go play in the park
216 | come back before the sky turns dark
217 | ```
218 |
219 | **8)** Display the third line from the given `stdin` data. Consider the NUL character as the line separator.
220 |
221 | ```bash
222 | $ printf 'apple\0fig\0carpet\0jeep\0bus\0' | head -z -n3 | tail -z -n1
223 | carpet
224 | ```
225 |
226 |
227 |
228 | # tr
229 |
230 | **1)** What's wrong with the following command?
231 |
232 | ```bash
233 | $ echo 'apple#banana#cherry' | tr # :
234 | tr: missing operand
235 | Try 'tr --help' for more information.
236 |
237 | $ echo 'apple#banana#cherry' | tr '#' ':'
238 | apple:banana:cherry
239 | ```
240 |
241 | As a good practice, always quote the arguments passed to the `tr` command to avoid conflict with shell metacharacters. Unless of course, you need the shell to interpret them.
242 |
243 | **2)** Retain only alphabets, digits and whitespace characters.
244 |
245 | ```bash
246 | $ printf 'Apple_42 cool,blue\tDragon:army\n' | tr -dc '[:alnum:][:space:]'
247 | Apple42 coolblue Dragonarmy
248 | ```
249 |
250 | **3)** Similar to rot13, figure out a way to shift digits such that the same logic can be used both ways.
251 |
252 | ```bash
253 | $ echo '4780 89073' | tr '0-9' '5-90-4'
254 | 9235 34528
255 |
256 | $ echo '9235 34528' | tr '0-9' '5-90-4'
257 | 4780 89073
258 | ```
259 |
260 | **4)** Figure out the logic based on the given input and output data. Hint: use two ranges for the first set and only 6 characters in the second set.
261 |
262 | ```bash
263 | $ echo 'apple banana cherry damson etrog' | tr 'a-ep-z' '12345X'
264 | 1XXl5 21n1n1 3h5XXX 41mXon 5XXog
265 | ```
266 |
267 | **5)** Which option would you use to truncate the first set so that it matches the length of the second set?
268 |
269 | The `-t` option is needed for this.
270 |
271 | **6)** What does the `*` notation do in the second set?
272 |
273 | The `[c*n]` notation repeats a character `c` by `n` times. You can specify `n` in decimal or octal formats. If `n` is omitted, the character `c` is repeated as many times as needed to equalize the length of the sets.
274 |
275 | **7)** Change `:` to `-` and `;` to the newline character.
276 |
277 | ```bash
278 | $ echo 'tea:coffee;brown:teal;dragon:unicorn' | tr ':;' '-\n'
279 | tea-coffee
280 | brown-teal
281 | dragon-unicorn
282 | ```
283 |
284 | **8)** Convert all characters to `*` except digit and newline characters.
285 |
286 | ```bash
287 | $ echo 'ajsd45_sdg2Khnf4v_54as' | tr -c '0-9\n' '*'
288 | ****45****2****4**54**
289 | ```
290 |
291 | **9)** Change consecutive repeated punctuation characters to a single punctuation character.
292 |
293 | ```bash
294 | $ echo '""hi..."", good morning!!!!' | tr -s '[:punct:]'
295 | "hi.", good morning!
296 | ```
297 |
298 | **10)** Figure out the logic based on the given input and output data.
299 |
300 | ```bash
301 | $ echo 'Aapple noon banana!!!!!' | tr -cs 'a-z\n' ':'
302 | :apple:noon:banana:
303 | ```
304 |
305 | **11)** The `books.txt` file has items separated by one or more `:` characters. Change this separator to a single newline character as shown below.
306 |
307 | ```bash
308 | $ cat books.txt
309 | Cradle:::Mage Errant::The Weirkey Chronicles
310 | Mother of Learning::Eight:::::Dear Spellbook:Ascendant
311 | Mark of the Fool:Super Powereds:::Ends of Magic
312 |
313 | $
327 |
328 | # cut
329 |
330 | **1)** Display only the third field.
331 |
332 | ```bash
333 | $ printf 'tea\tcoffee\tchocolate\tfruit\n' | cut -f3
334 | chocolate
335 | ```
336 |
337 | **2)** Display the second and fifth fields. Consider `,` as the field separator.
338 |
339 | ```bash
340 | $ echo 'tea,coffee,chocolate,ice cream,fruit' | cut -d, -f2,5
341 | coffee,fruit
342 | ```
343 |
344 | **3)** Why does the below command not work as expected? What other tools can you use in such cases?
345 |
346 | `cut` ignores all repeated fields and the output is always presented in the ascending order.
347 |
348 | ```bash
349 | # not working as expected
350 | $ echo 'apple,banana,cherry,fig' | cut -d, -f3,1,3
351 | apple,cherry
352 |
353 | # expected output
354 | $ echo 'apple,banana,cherry,fig' | awk -F, -v OFS=, '{print $3, $1, $3}'
355 | cherry,apple,cherry
356 | ```
357 |
358 | **4)** Display except the second field in the format shown below. Can you construct two different solutions?
359 |
360 | ```bash
361 | # solution 1
362 | $ echo 'apple,banana,cherry,fig' | cut -d, --output-delimiter=' ' -f1,3-
363 | apple cherry fig
364 |
365 | # solution 2
366 | $ echo '2,3,4,5,6,7,8' | cut -d, --output-delimiter=' ' --complement -f2
367 | 2 4 5 6 7 8
368 | ```
369 |
370 | **5)** Extract the first three characters from the input lines as shown below. Can you also use the `head` command for this purpose? If not, why not?
371 |
372 | ```bash
373 | $ printf 'apple\nbanana\ncherry\nfig\n' | cut -c-3
374 | app
375 | ban
376 | che
377 | fig
378 | ```
379 |
380 | `head` cannot be used because it acts on the input as a whole, whereas `cut` works line wise.
381 |
382 | **6)** Display only the first and third fields of the `scores.csv` input file, with tab as the output field separator.
383 |
384 | ```bash
385 | $ cat scores.csv
386 | Name,Maths,Physics,Chemistry
387 | Ith,100,100,100
388 | Cy,97,98,95
389 | Lin,78,83,80
390 |
391 | $ cut -d, --output-delimiter=$'\t' -f1,3 scores.csv
392 | Name Physics
393 | Ith 100
394 | Cy 98
395 | Lin 83
396 | ```
397 |
398 | **7)** The given input data uses one or more `:` characters as the field separator. Assume that no field content will have the `:` character. Display except the second field, with ` : ` as the output field separator.
399 |
400 | ```bash
401 | $ cat books.txt
402 | Cradle:::Mage Errant::The Weirkey Chronicles
403 | Mother of Learning::Eight:::::Dear Spellbook:Ascendant
404 | Mark of the Fool:Super Powereds:::Ends of Magic
405 |
406 | $
438 |
439 | # seq
440 |
441 | **1)** Generate numbers from `42` to `45` in ascending order.
442 |
443 | ```bash
444 | $ seq 42 45
445 | 42
446 | 43
447 | 44
448 | 45
449 | ```
450 |
451 | **2)** Why does the command shown below produce no output?
452 |
453 | You have to explicitly provide a negative step value to generate numbers in descending order.
454 |
455 | ```bash
456 | # no output
457 | $ seq 45 42
458 |
459 | # expected output
460 | $ seq 45 -1 42
461 | 45
462 | 44
463 | 43
464 | 42
465 | ```
466 |
467 | **3)** Generate numbers from `25` to `10` in descending order, with a step value of `5`.
468 |
469 | ```bash
470 | $ seq 25 -5 10
471 | 25
472 | 20
473 | 15
474 | 10
475 | ```
476 |
477 | **4)** Is the sequence shown below possible to generate with `seq`? If so, how?
478 |
479 | ```bash
480 | $ seq -w -s, 01.5 6
481 | 01.5,02.5,03.5,04.5,05.5
482 | ```
483 |
484 | **5)** Modify the command shown below to customize the output numbering format.
485 |
486 | ```bash
487 | $ seq 30.14 3.36 40.72
488 | 30.14
489 | 33.50
490 | 36.86
491 | 40.22
492 |
493 | $ seq -f'%.3e' 30.14 3.36 40.72
494 | 3.014e+01
495 | 3.350e+01
496 | 3.686e+01
497 | 4.022e+01
498 | ```
499 |
500 |
501 |
502 | # shuf
503 |
504 | **1)** What's wrong with the given command?
505 |
506 | `shuf` doesn't accept multiple input files. You can use `cat` to concatenate them first.
507 |
508 | ```bash
509 | $ shuf --random-source=greeting.txt fruits.txt books.txt
510 | shuf: extra operand ‘books.txt’
511 | Try 'shuf --help' for more information.
512 |
513 | # expected output
514 | $ cat fruits.txt books.txt | shuf --random-source=greeting.txt
515 | banana
516 | Cradle:::Mage Errant::The Weirkey Chronicles
517 | Mother of Learning::Eight:::::Dear Spellbook:Ascendant
518 | papaya
519 | Mark of the Fool:Super Powereds:::Ends of Magic
520 | mango
521 | ```
522 |
523 | **2)** What do the `-r` and `-n` options do? Why are they often used together?
524 |
525 | The `-r` option helps if you want to allow input lines to be repeated. This option is usually paired with `-n` to limit the number of lines in the output. Otherwise, `shuf -r` will produce output lines indefinitely.
526 |
527 | **3)** What does the following command do?
528 |
529 | The `-e` option is useful to specify multiple input lines as arguments to the command.
530 |
531 | ```bash
532 | $ shuf -e apple banana cherry fig mango
533 | cherry
534 | banana
535 | mango
536 | fig
537 | apple
538 | ```
539 |
540 | **4)** Which option would you use to generate random numbers? Given an example.
541 |
542 | The `-i` option helps generate random positive integers.
543 |
544 | ```bash
545 | $ shuf -n3 -i 100-200
546 | 128
547 | 177
548 | 193
549 | ```
550 |
551 | **5)** How would you generate 5 random numbers between `0.125` and `0.789` with a step value of `0.023`?
552 |
553 | ```bash
554 | $ seq 0.125 0.023 0.789 | shuf -n5
555 | 0.378
556 | 0.631
557 | 0.447
558 | 0.746
559 | 0.723
560 | ```
561 |
562 |
563 |
564 | # paste
565 |
566 | **1)** What's the default delimiter character added by the `paste` command? Which option would you use to customize this separator?
567 |
568 | Tab. You can use the `-d` option to change the delimiter between the columns.
569 |
570 | **2)** Will the following two commands produce equivalent output? If not, why not?
571 |
572 | ```bash
573 | $ paste -d, <(seq 3) <(printf '%s\n' item_{1..3})
574 | 1,item_1
575 | 2,item_2
576 | 3,item_3
577 |
578 | $ printf '%s\n' {1..3},item_{1..3}
579 | 1,item_1
580 | 1,item_2
581 | 1,item_3
582 | 2,item_1
583 | 2,item_2
584 | 2,item_3
585 | 3,item_1
586 | 3,item_2
587 | 3,item_3
588 | ```
589 |
590 | The outputs are not equivalent because brace expansion creates all combinations when multiple braces are used.
591 |
592 | **3)** Combine the two data sources as shown below.
593 |
594 | ```bash
595 | $ printf '1)\n2)\n3)'
596 | 1)
597 | 2)
598 | 3)
599 | $ cat fruits.txt
600 | banana
601 | papaya
602 | mango
603 |
604 | $ paste -d '' <(printf '1)\n2)\n3)') fruits.txt
605 | 1)banana
606 | 2)papaya
607 | 3)mango
608 | ```
609 |
610 | **4)** Interleave the contents of `fruits.txt` and `books.txt`.
611 |
612 | ```bash
613 | $ paste -d'\n' fruits.txt books.txt
614 | banana
615 | Cradle:::Mage Errant::The Weirkey Chronicles
616 | papaya
617 | Mother of Learning::Eight:::::Dear Spellbook:Ascendant
618 | mango
619 | Mark of the Fool:Super Powereds:::Ends of Magic
620 | ```
621 |
622 | **5)** Generate numbers `1` to `9` in two different formats as shown below.
623 |
624 | ```bash
625 | $ seq 9 | paste -d: - - -
626 | 1:2:3
627 | 4:5:6
628 | 7:8:9
629 |
630 | $ paste -d' : ' <(seq 3) /dev/null /dev/null <(seq 4 6) /dev/null /dev/null <(seq 7 9)
631 | 1 : 4 : 7
632 | 2 : 5 : 8
633 | 3 : 6 : 9
634 | ```
635 |
636 | **6)** Combine the contents of `fruits.txt` and `colors.txt` as shown below.
637 |
638 | ```bash
639 | $ cat fruits.txt
640 | banana
641 | papaya
642 | mango
643 | $ cat colors.txt
644 | deep blue
645 | light orange
646 | blue delight
647 |
648 | $ paste -d'\n' fruits.txt colors.txt | paste -sd,
649 | banana,deep blue,papaya,light orange,mango,blue delight
650 | ```
651 |
652 |
653 |
654 | # pr
655 |
656 | **1)** What does the `-t` option do?
657 |
658 | The `-t` option turns off the pagination features like headers and trailers.
659 |
660 | **2)** Generate numbers `1` to `16` in two different formats as shown below.
661 |
662 | ```bash
663 | $ seq -w 16 | pr -4ats,
664 | 01,02,03,04
665 | 05,06,07,08
666 | 09,10,11,12
667 | 13,14,15,16
668 |
669 | $ seq -w 16 | pr -4ts,
670 | 01,05,09,13
671 | 02,06,10,14
672 | 03,07,11,15
673 | 04,08,12,16
674 | ```
675 |
676 | **3)** How'd you solve the issue shown below?
677 |
678 | ```bash
679 | $ seq 100 | pr -37ats,
680 | pr: page width too narrow
681 |
682 | $ seq 100 | pr -J -w73 -37ats,
683 | 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37
684 | 38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74
685 | 75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100
686 | ```
687 |
688 | `(N-1)*length(separator) + N` is the minimum page width you need, where `N` is the number of columns required. So, for `37` columns and a separator of length `1`, you'll need a minimum width of `73`. `-J` option ensures input lines aren't truncated.
689 |
690 | **4)** Combine the contents of `fruits.txt` and `colors.txt` in two different formats as shown below.
691 |
692 | ```bash
693 | $ cat fruits.txt
694 | banana
695 | papaya
696 | mango
697 | $ cat colors.txt
698 | deep blue
699 | light orange
700 | blue delight
701 |
702 | $ pr -mts' : ' fruits.txt colors.txt
703 | banana : deep blue
704 | papaya : light orange
705 | mango : blue delight
706 |
707 | $ pr -n:2 -mts, fruits.txt colors.txt
708 | 1:banana,deep blue
709 | 2:papaya,light orange
710 | 3:mango,blue delight
711 | ```
712 |
713 | **5)** What does the `-d` option do?
714 |
715 | You can use the `-d` option to double space the input contents. That is, every newline character is doubled.
716 |
717 |
718 |
719 | # fold and fmt
720 |
721 | **1)** What's the default wrap length of the `fold` and `fmt` commands?
722 |
723 | `80` bytes and `93%` of `75` columns respectively.
724 |
725 | **2)** Fold the given `stdin` data at 9 bytes.
726 |
727 | ```bash
728 | $ echo 'hi hello, how are you?' | fold -w9
729 | hi hello,
730 | how are
731 | you?
732 | ```
733 |
734 | **3)** Figure out the logic based on the given input and output data using the `fold` command.
735 |
736 | ```bash
737 | $ cat ip.txt
738 | it is a warm and cozy day
739 | listen to what I say
740 | go play in the park
741 | come back before the sky turns dark
742 |
743 | There are so many delights to cherish
744 | Apple, Banana and Cherry
745 | Bread, Butter and Jelly
746 | Try them all before you perish
747 |
748 | $ head -n2 ip.txt | fold -sw10
749 | it is a
750 | warm and
751 | cozy day
752 | listen to
753 | what I say
754 | ```
755 |
756 | **4)** What does the `fold -b` option do?
757 |
758 | The `-b` option will cause `fold` to treat tab, backspace, and carriage return characters as if they were a single byte character.
759 |
760 | **5)** How'd you get the expected output shown below?
761 |
762 | ```bash
763 | # wrong output
764 | $ echo 'fig appleseed mango pomegranate' | fold -sw7
765 | fig
766 | applese
767 | ed
768 | mango
769 | pomegra
770 | nate
771 |
772 | # expected output
773 | $ echo 'fig appleseed mango pomegranate' | fmt -w7
774 | fig
775 | appleseed
776 | mango
777 | pomegranate
778 | ```
779 |
780 | **6)** What do the options `-s` and `-u` of the `fmt` command do?
781 |
782 | By default, the `fmt` command joins lines together that are shorter than the specified width. The `-s` option will disable this behavior.
783 |
784 | The `-u` option changes multiple spaces to a single space. Excess spacing between sentences will be changed to two spaces.
785 |
786 |
787 |
788 | # sort
789 |
790 | **1)** Default `sort` doesn't work for numbers. Which option would you use to get the expected output shown below?
791 |
792 | ```bash
793 | $ printf '100\n10\n20\n3000\n2.45\n' | sort -n
794 | 2.45
795 | 10
796 | 20
797 | 100
798 | 3000
799 | ```
800 |
801 | **2)** Which `sort` option will help you ignore case? `LC_ALL=C` is used here to avoid differences due to locale.
802 |
803 | ```bash
804 | $ printf 'Super\nover\nRUNE\ntea\n' | LC_ALL=C sort -f
805 | over
806 | RUNE
807 | Super
808 | tea
809 | ```
810 |
811 | **3)** The `-n` option doesn't work for all sorts of numbers. Which `sort` option would you use to get the expected output shown below?
812 |
813 | ```bash
814 | # wrong output
815 | $ printf '+120\n-1.53\n3.14e+4\n42.1e-2' | sort -n
816 | -1.53
817 | +120
818 | 3.14e+4
819 | 42.1e-2
820 |
821 | # expected output
822 | $ printf '+120\n-1.53\n3.14e+4\n42.1e-2' | sort -g
823 | -1.53
824 | 42.1e-2
825 | +120
826 | 3.14e+4
827 | ```
828 |
829 | **4)** What do the `-V` and `-h` options do?
830 |
831 | The `-V` option is useful when you have a mix of alphabets and digits. It also helps when you want to treat digits after a decimal point as whole numbers, for example `1.10` should be greater than `1.2`.
832 |
833 | Commands like `du` (disk usage) have the `-h` and `--si` options to display numbers with [SI suffixes](https://en.wikipedia.org/wiki/International_System_of_Units) like `k`, `K`, `M`, `G` and so on. In such cases, you can use `sort -h` to order them.
834 |
835 | **5)** Is there a difference between `shuf` and `sort -R`?
836 |
837 | The `sort -R` option will display the output in random order. Unlike `shuf`, this option will always place identical lines next to each other due to the implementation.
838 |
839 | **6)** Sort the `scores.csv` file numerically in ascending order using the contents of the second field. Header line should be preserved as the first line as shown below.
840 |
841 | ```bash
842 | $ cat scores.csv
843 | Name,Maths,Physics,Chemistry
844 | Ith,100,100,100
845 | Cy,97,98,95
846 | Lin,78,83,80
847 |
848 | $ (sed -u '1q' ; sort -t, -k2,2n) < scores.csv
849 | Name,Maths,Physics,Chemistry
850 | Lin,78,83,80
851 | Cy,97,98,95
852 | Ith,100,100,100
853 | ```
854 |
855 | **7)** Sort the contents of `duplicates.csv` by the fourth column numbers in descending order. Retain only the first copy of lines with the same number.
856 |
857 | ```bash
858 | $ cat duplicates.csv
859 | brown,toy,bread,42
860 | dark red,ruby,rose,111
861 | blue,ruby,water,333
862 | dark red,sky,rose,555
863 | yellow,toy,flower,333
864 | white,sky,bread,111
865 | light red,purse,rose,333
866 |
867 | $ sort -t, -k4,4nr -u duplicates.csv
868 | dark red,sky,rose,555
869 | blue,ruby,water,333
870 | dark red,ruby,rose,111
871 | brown,toy,bread,42
872 | ```
873 |
874 | **8)** Sort the contents of `duplicates.csv` by the third column item. Use the fourth column numbers as the tie-breaker.
875 |
876 | ```bash
877 | $ sort -t, -k3,3 -k4,4n duplicates.csv
878 | brown,toy,bread,42
879 | white,sky,bread,111
880 | yellow,toy,flower,333
881 | dark red,ruby,rose,111
882 | light red,purse,rose,333
883 | dark red,sky,rose,555
884 | blue,ruby,water,333
885 | ```
886 |
887 | **9)** What does the `-s` option provide?
888 |
889 | The `-s` option is useful to retain the original order of input lines when two or more lines are deemed equal.
890 |
891 | **10)** Sort the given input based on the numbers inside the brackets.
892 |
893 | ```bash
894 | $ printf '(-3.14)\n[45]\n(12.5)\n{14093}' | sort -k1.2n
895 | (-3.14)
896 | (12.5)
897 | [45]
898 | {14093}
899 | ```
900 |
901 | **11)** What do the `-c`, `-C` and `-m` options do?
902 |
903 | The `-c` option helps you spot the first unsorted entry in the given input. The uppercase `-C` option is similar but only affects the exit status. Note that these options will not work for multiple inputs.
904 |
905 | The `-m` option is useful if you have one or more sorted input files and need a single sorted output file. This would be faster than normal sorting.
906 |
907 |
908 |
909 | # uniq
910 |
911 | **1)** Will `uniq` throw an error if the input is not sorted? What do you think will be the output for the following input?
912 |
913 | `uniq` doesn't necessarily require the input to be sorted. Adjacent lines are used for comparison purposes.
914 |
915 | ```bash
916 | $ printf 'red\nred\nred\ngreen\nred\nblue\nblue' | uniq
917 | red
918 | green
919 | red
920 | blue
921 | ```
922 |
923 | **2)** Are there differences between `sort -u file` and `sort file | uniq`?
924 |
925 | Yes. For example, you may need to sort based on some specific criteria and then identify duplicates based on the entire line contents. Here's an example:
926 |
927 | ```bash
928 | # can't use sort -n -u here
929 | $ printf '2 balls\n13 pens\n2 pins\n13 pens\n' | sort -n | uniq
930 | 2 balls
931 | 2 pins
932 | 13 pens
933 | ```
934 |
935 | **3)** What are the differences between `sort -u` and `uniq -u` options, if any?
936 |
937 | `sort -u` retains the first copy of duplicates that are deemed to be equal. `uniq -u` retains only the unique copies (i.e. not even a single copy of the duplicates will be part of the output).
938 |
939 | **4)** Filter the third column items from `duplicates.csv`. Construct three solutions to display only unique items, duplicate items and all duplicates.
940 |
941 | ```bash
942 | $ cat duplicates.csv
943 | brown,toy,bread,42
944 | dark red,ruby,rose,111
945 | blue,ruby,water,333
946 | dark red,sky,rose,555
947 | yellow,toy,flower,333
948 | white,sky,bread,111
949 | light red,purse,rose,333
950 |
951 | # unique
952 | $ cut -d, -f3 duplicates.csv | sort | uniq -u
953 | flower
954 | water
955 |
956 | # duplicates
957 | $ cut -d, -f3 duplicates.csv | sort | uniq -d
958 | bread
959 | rose
960 |
961 | # all duplicates
962 | $ cut -d, -f3 duplicates.csv | sort | uniq -D
963 | bread
964 | bread
965 | rose
966 | rose
967 | rose
968 | ```
969 |
970 | **5)** What does the `--group` option do? What customization features are available?
971 |
972 | The `--group` options allows you to visually separate groups of similar lines with an empty line. This option can accept four values — `separate`, `prepend`, `append` and `both`. The default is `separate`, which adds a newline character between the groups. `prepend` will add a newline before the first group as well and `append` will add a newline after the last group. `both` combines the `prepend` and `append` behavior.
973 |
974 | **6)** Count the number of times input lines are repeated and display the results in the format shown below.
975 |
976 | ```bash
977 | $ s='brown\nbrown\nbrown\ngreen\nbrown\nblue\nblue'
978 | $ printf '%b' "$s" | sort | uniq -c | sort -n
979 | 1 green
980 | 2 blue
981 | 4 brown
982 | ```
983 |
984 | **7)** For the input file `f1.txt`, retain only unique entries based on the first two characters of each line. For example, `abcd` and `ab12` should be considered as duplicates and neither of them will be part of the output.
985 |
986 | ```bash
987 | $ cat f1.txt
988 | 3) cherry
989 | 1) apple
990 | 2) banana
991 | 1) almond
992 | 4) mango
993 | 2) berry
994 | 3) chocolate
995 | 1) apple
996 | 5) cherry
997 |
998 | $ sort f1.txt | uniq -u -w2
999 | 4) mango
1000 | 5) cherry
1001 | ```
1002 |
1003 | **8)** For the input file `f1.txt`, display only the duplicate items without considering the first two characters of each line. For example, `abcd` and `12cd` should be considered as duplicates. Assume that the third character of each line is always a space character.
1004 |
1005 | ```bash
1006 | $ sort -k2 f1.txt | uniq -d -f1
1007 | 1) apple
1008 | 3) cherry
1009 | ```
1010 |
1011 | **9)** What does the `-s` option do?
1012 |
1013 | The `-s` option allows you to skip the first `N` characters (calculated as bytes).
1014 |
1015 | **10)** Filter only unique lines, but ignore differences due to case.
1016 |
1017 | ```bash
1018 | $ printf 'cat\nbat\nCAT\nCar\nBat\nmat\nMat' | sort -f | uniq -iu
1019 | Car
1020 | ```
1021 |
1022 |
1023 |
1024 | # comm
1025 |
1026 | **1)** Get the common lines between the `s1.txt` and `s2.txt` files. Assume that their contents are already sorted.
1027 |
1028 | ```bash
1029 | $ paste s1.txt s2.txt
1030 | apple banana
1031 | coffee coffee
1032 | fig eclair
1033 | honey fig
1034 | mango honey
1035 | pasta milk
1036 | sugar tea
1037 | tea yeast
1038 |
1039 | $ comm -12 s1.txt s2.txt
1040 | coffee
1041 | fig
1042 | honey
1043 | tea
1044 | ```
1045 |
1046 | **2)** Display lines present in `s1.txt` but not `s2.txt` and vice versa.
1047 |
1048 | ```bash
1049 | # lines unique to the first file
1050 | $ comm -23 s1.txt s2.txt
1051 | apple
1052 | mango
1053 | pasta
1054 | sugar
1055 |
1056 | # lines unique to the second file
1057 | $ comm -13 s1.txt s2.txt
1058 | banana
1059 | eclair
1060 | milk
1061 | yeast
1062 | ```
1063 |
1064 | **3)** Display lines unique to the `s1.txt` file and the common lines when compared to the `s2.txt` file. Use `==>` to separate the output columns.
1065 |
1066 | ```bash
1067 | $ comm -2 --output-delimiter='==>' s1.txt s2.txt
1068 | apple
1069 | ==>coffee
1070 | ==>fig
1071 | ==>honey
1072 | mango
1073 | pasta
1074 | sugar
1075 | ==>tea
1076 | ```
1077 |
1078 | **4)** What does the `--total` option do?
1079 |
1080 | Gives you the count of lines for each of the three columns.
1081 |
1082 | **5)** Will the `comm` command fail if there are repeated lines in the input files? If not, what'd be the expected output for the command shown below?
1083 |
1084 | The number of duplicate lines in the common column will be minimum of the duplicate occurrences between the two files. Rest of the duplicate lines, if any, will be considered as unique to the file having the excess lines.
1085 |
1086 | ```bash
1087 | $ cat s3.txt
1088 | apple
1089 | apple
1090 | guava
1091 | honey
1092 | tea
1093 | tea
1094 | tea
1095 |
1096 | $ comm -23 s3.txt s1.txt
1097 | apple
1098 | guava
1099 | tea
1100 | tea
1101 | ```
1102 |
1103 |
1104 |
1105 | # join
1106 |
1107 | > Assume that the input files are already sorted for these exercises.
1108 |
1109 | **1)** Use appropriate options to get the expected outputs shown below.
1110 |
1111 | ```bash
1112 | # no output
1113 | $ join <(printf 'apple 2\nfig 5') <(printf 'Fig 10\nmango 4')
1114 |
1115 | # expected output 1
1116 | $ join -i <(printf 'apple 2\nfig 5') <(printf 'Fig 10\nmango 4')
1117 | fig 5 10
1118 |
1119 | # expected output 2
1120 | $ join -i -a1 -a2 <(printf 'apple 2\nfig 5') <(printf 'Fig 10\nmango 4')
1121 | apple 2
1122 | fig 5 10
1123 | mango 4
1124 | ```
1125 |
1126 | **2)** Use the `join` command to display only the non-matching lines based on the first field.
1127 |
1128 | ```bash
1129 | $ cat j1.txt
1130 | apple 2
1131 | fig 5
1132 | lemon 10
1133 | tomato 22
1134 | $ cat j2.txt
1135 | almond 33
1136 | fig 115
1137 | mango 20
1138 | pista 42
1139 |
1140 | # first field items present in j1.txt but not j2.txt
1141 | $ join -v1 j1.txt j2.txt
1142 | apple 2
1143 | lemon 10
1144 | tomato 22
1145 |
1146 | # first field items present in j2.txt but not j1.txt
1147 | $ join -v2 j1.txt j2.txt
1148 | almond 33
1149 | mango 20
1150 | pista 42
1151 | ```
1152 |
1153 | **3)** Filter lines from `j1.txt` and `j2.txt` that match the items from `s1.txt`.
1154 |
1155 | ```bash
1156 | $ cat s1.txt
1157 | apple
1158 | coffee
1159 | fig
1160 | honey
1161 | mango
1162 | pasta
1163 | sugar
1164 | tea
1165 |
1166 | # note that sort -m is used since the input files are already sorted
1167 | $ join s1.txt <(sort -m j1.txt j2.txt)
1168 | apple 2
1169 | fig 115
1170 | fig 5
1171 | mango 20
1172 | ```
1173 |
1174 | **4)** Join the `marks_1.csv` and `marks_2.csv` files to get the expected output shown below.
1175 |
1176 | ```bash
1177 | $ cat marks_1.csv
1178 | Name,Biology,Programming
1179 | Er,92,77
1180 | Ith,100,100
1181 | Lin,92,100
1182 | Sil,86,98
1183 | $ cat marks_2.csv
1184 | Name,Maths,Physics,Chemistry
1185 | Cy,97,98,95
1186 | Ith,100,100,100
1187 | Lin,78,83,80
1188 |
1189 | $ join -t, --header marks_1.csv marks_2.csv
1190 | Name,Biology,Programming,Maths,Physics,Chemistry
1191 | Ith,100,100,100,100,100
1192 | Lin,92,100,78,83,80
1193 | ```
1194 |
1195 | **5)** By default, the first field is used to combine the lines. Which options are helpful if you want to change the key field to be used for joining?
1196 |
1197 | You can use `-1` and `-2` options followed by a field number to specify a different field number. You can use the `-j` option if the field number is the same for both the files.
1198 |
1199 | **6)** Join the `marks_1.csv` and `marks_2.csv` files to get the expected output with specific fields as shown below.
1200 |
1201 | ```bash
1202 | $ join -t, --header -o 1.1,1.3,2.2,1.2 marks_1.csv marks_2.csv
1203 | Name,Programming,Maths,Biology
1204 | Ith,100,100,100
1205 | Lin,100,78,92
1206 | ```
1207 |
1208 | **7)** Join the `marks_1.csv` and `marks_2.csv` files to get the expected output shown below. Use `50` as the filler data.
1209 |
1210 | ```bash
1211 | $ join -t, --header -o auto -a1 -a2 -e '50' marks_1.csv marks_2.csv
1212 | Name,Biology,Programming,Maths,Physics,Chemistry
1213 | Cy,50,50,97,98,95
1214 | Er,92,77,50,50,50
1215 | Ith,100,100,100,100,100
1216 | Lin,92,100,78,83,80
1217 | Sil,86,98,50,50,50
1218 | ```
1219 |
1220 | **8)** When you use the `-o auto` option, what'd happen to the extra fields compared to those in the first lines of the input data?
1221 |
1222 | If you use `auto` as the argument for the `-o` option, first line of both the input files will be used to determine the number of output fields. If the other lines have extra fields, they will be discarded.
1223 |
1224 | **9)** From the input files `j3.txt` and `j4.txt`, filter only the lines are unique — i.e. lines that are not common to these files. Assume that the input files do not have duplicate entries.
1225 |
1226 | ```bash
1227 | $ cat j3.txt
1228 | almond
1229 | apple pie
1230 | cold coffee
1231 | honey
1232 | mango shake
1233 | pasta
1234 | sugar
1235 | tea
1236 | $ cat j4.txt
1237 | apple
1238 | banana shake
1239 | coffee
1240 | fig
1241 | honey
1242 | mango shake
1243 | milk
1244 | tea
1245 | yeast
1246 |
1247 | $ join -t '' -v1 -v2 j3.txt j4.txt
1248 | almond
1249 | apple
1250 | apple pie
1251 | banana shake
1252 | coffee
1253 | cold coffee
1254 | fig
1255 | milk
1256 | pasta
1257 | sugar
1258 | yeast
1259 | ```
1260 |
1261 | **10)** From the input files `j3.txt` and `j4.txt`, filter only the lines are common to these files.
1262 |
1263 | ```bash
1264 | $ join -t '' j3.txt j4.txt
1265 | honey
1266 | mango shake
1267 | tea
1268 | ```
1269 |
1270 |
1271 |
1272 | # nl
1273 |
1274 | **1)** `nl` and `cat -n` are always equivalent for numbering lines. True or False?
1275 |
1276 | True if there are no empty lines in the input data. `cat -b` and `nl` are always equivalent.
1277 |
1278 | **2)** What does the `-n` option do?
1279 |
1280 | You can use the `-n` option to customize the number formatting. The available styles are:
1281 |
1282 | * `rn` right justified with space fillers (default)
1283 | * `rz` right justified with leading zeros
1284 | * `ln` left justified with space fillers
1285 |
1286 | **3)** Use `nl` to produce the two expected outputs shown below.
1287 |
1288 | ```bash
1289 | $ cat greeting.txt
1290 | Hi there
1291 | Have a nice day
1292 |
1293 | # expected output 1
1294 | $ nl -w3 -n'rz' greeting.txt
1295 | 001 Hi there
1296 | 002 Have a nice day
1297 |
1298 | # expected output 2
1299 | $ nl -w3 -n'rz' -s') ' greeting.txt
1300 | 001) Hi there
1301 | 002) Have a nice day
1302 | ```
1303 |
1304 | **4)** Figure out the logic based on the given input and output data.
1305 |
1306 | ```bash
1307 | $ cat s1.txt
1308 | apple
1309 | coffee
1310 | fig
1311 | honey
1312 | mango
1313 | pasta
1314 | sugar
1315 | tea
1316 |
1317 | $ nl -w2 -s'. ' -v15 -i-2 s1.txt
1318 | 15. apple
1319 | 13. coffee
1320 | 11. fig
1321 | 9. honey
1322 | 7. mango
1323 | 5. pasta
1324 | 3. sugar
1325 | 1. tea
1326 | ```
1327 |
1328 | **5)** What are the three types of sections supported by `nl`?
1329 |
1330 | `nl` recognizes three types of sections with the following default patterns:
1331 |
1332 | * `\:\:\:` as header
1333 | * `\:\:` as body
1334 | * `\:` as footer
1335 |
1336 | These special lines will be replaced with an empty line after numbering. The numbering will be reset at the start of every section unless the `-p` option is used.
1337 |
1338 | **6)** Only number the lines that start with `----` in the format shown below.
1339 |
1340 | ```bash
1341 | $ cat blocks.txt
1342 | ----
1343 | apple--banana
1344 | mango---fig
1345 | ----
1346 | 3.14
1347 | -42
1348 | 1000
1349 | ----
1350 | sky blue
1351 | dark green
1352 | ----
1353 | hi hello
1354 |
1355 | $ nl -w2 -s') ' -bp'^----' blocks.txt
1356 | 1) ----
1357 | apple--banana
1358 | mango---fig
1359 | 2) ----
1360 | 3.14
1361 | -42
1362 | 1000
1363 | 3) ----
1364 | sky blue
1365 | dark green
1366 | 4) ----
1367 | hi hello
1368 | ```
1369 |
1370 | **7)** For the `blocks.txt` file, determine the logic to produce the expected output shown below.
1371 |
1372 | ```bash
1373 | $ nl -w1 -s'. ' -d'--' blocks.txt
1374 |
1375 | 1. apple--banana
1376 | 2. mango---fig
1377 |
1378 | 1. 3.14
1379 | 2. -42
1380 | 3. 1000
1381 |
1382 | 1. sky blue
1383 | 2. dark green
1384 |
1385 | 1. hi hello
1386 | ```
1387 |
1388 | **8)** What does the `-l` option do?
1389 |
1390 | The `-l` option controls how many consecutive empty lines should be considered as a single entry. Only the last empty line of such groupings will be numbered.
1391 |
1392 | **9)** Figure out the logic based on the given input and output data.
1393 |
1394 | ```bash
1395 | $ cat all_sections.txt
1396 | \:\:\:
1397 | Header
1398 | teal
1399 | \:\:
1400 | Hi there
1401 | How are you
1402 | \:\:
1403 | banana
1404 | papaya
1405 | mango
1406 | \:
1407 | Footer
1408 |
1409 | $ nl -p -w2 -s') ' -ha all_sections.txt
1410 |
1411 | 1) Header
1412 | 2) teal
1413 |
1414 | 3) Hi there
1415 | 4) How are you
1416 |
1417 | 5) banana
1418 | 6) papaya
1419 | 7) mango
1420 |
1421 | Footer
1422 | ```
1423 |
1424 |
1425 |
1426 | # wc
1427 |
1428 | **1)** Save the number of lines in the `greeting.txt` input file to the `lines` shell variable.
1429 |
1430 | ```bash
1431 | $ lines=$(wc -l
1495 |
1496 | # split
1497 |
1498 | > Remove the output files after every exercise.
1499 |
1500 | **1)** Split the `s1.txt` file 3 lines at a time.
1501 |
1502 | ```bash
1503 | $ split -l3 s1.txt
1504 |
1505 | $ head xa?
1506 | ==> xaa <==
1507 | apple
1508 | coffee
1509 | fig
1510 |
1511 | ==> xab <==
1512 | honey
1513 | mango
1514 | pasta
1515 |
1516 | ==> xac <==
1517 | sugar
1518 | tea
1519 |
1520 | $ rm xa?
1521 | ```
1522 |
1523 | **2)** Use appropriate options to get the output shown below.
1524 |
1525 | ```bash
1526 | $ echo 'apple,banana,cherry,dates' | split -t, -l1
1527 |
1528 | $ head xa?
1529 | ==> xaa <==
1530 | apple,
1531 | ==> xab <==
1532 | banana,
1533 | ==> xac <==
1534 | cherry,
1535 | ==> xad <==
1536 | dates
1537 |
1538 | $ rm xa?
1539 | ```
1540 |
1541 | **3)** What do the `-b` and `-C` options do?
1542 |
1543 | The `-b` option allows you to split the input by the number of bytes. This option also accepts suffixes such as `K` for `1024` bytes, `KB` for `1000` bytes, `M` for `1024 * 1024` bytes and so on.
1544 |
1545 | The `-C` option is similar to the `-b` option, but it will try to break on line boundaries if possible. The break will happen before the given byte limit. If a line exceeds the given limit, it will be broken down into multiple parts.
1546 |
1547 | **4)** Display the 2nd chunk of the `ip.txt` file after splitting it 4 times as shown below.
1548 |
1549 | ```bash
1550 | $ split -nl/2/4 ip.txt
1551 | come back before the sky turns dark
1552 |
1553 | There are so many delights to cherish
1554 | ```
1555 |
1556 | **5)** What does the `r` prefix do when used with the `-n` option?
1557 |
1558 | This creates output files with interleaved lines.
1559 |
1560 | **6)** Split the `ip.txt` file 2 lines at a time. Customize the output filenames as shown below.
1561 |
1562 | ```bash
1563 | $ split -l2 -a1 -d --additional-suffix='.txt' ip.txt ip_
1564 |
1565 | $ head ip_*
1566 | ==> ip_0.txt <==
1567 | it is a warm and cozy day
1568 | listen to what I say
1569 |
1570 | ==> ip_1.txt <==
1571 | go play in the park
1572 | come back before the sky turns dark
1573 |
1574 | ==> ip_2.txt <==
1575 |
1576 | There are so many delights to cherish
1577 |
1578 | ==> ip_3.txt <==
1579 | Apple, Banana and Cherry
1580 | Bread, Butter and Jelly
1581 |
1582 | ==> ip_4.txt <==
1583 | Try them all before you perish
1584 |
1585 | $ rm ip_*
1586 | ```
1587 |
1588 | **7)** Which option would you use to prevent empty files in the output?
1589 |
1590 | The `-e` option prevents empty files in the output.
1591 |
1592 | **8)** Split the `items.txt` file 5 lines at a time. Additionally, remove lines starting with a digit character as shown below.
1593 |
1594 | ```bash
1595 | $ cat items.txt
1596 | 1) fruits
1597 | apple 5
1598 | banana 10
1599 | 2) colors
1600 | green
1601 | sky blue
1602 | 3) magical beasts
1603 | dragon 3
1604 | unicorn 42
1605 |
1606 | $ split -l5 --filter='grep -v "^[0-9]" > $FILE' items.txt
1607 |
1608 | $ head xa?
1609 | ==> xaa <==
1610 | apple 5
1611 | banana 10
1612 | green
1613 |
1614 | ==> xab <==
1615 | sky blue
1616 | dragon 3
1617 | unicorn 42
1618 |
1619 | $ rm xa?
1620 | ```
1621 |
1622 |
1623 |
1624 | # csplit
1625 |
1626 | > Remove the output files after every exercise.
1627 |
1628 | **1)** Split the `blocks.txt` file such that the first 7 lines are in the first file and the rest are in the second file as shown below.
1629 |
1630 | ```bash
1631 | $ csplit -q blocks.txt 8
1632 |
1633 | $ head xx*
1634 | ==> xx00 <==
1635 | ----
1636 | apple--banana
1637 | mango---fig
1638 | ----
1639 | 3.14
1640 | -42
1641 | 1000
1642 |
1643 | ==> xx01 <==
1644 | ----
1645 | sky blue
1646 | dark green
1647 | ----
1648 | hi hello
1649 |
1650 | $ rm xx*
1651 | ```
1652 |
1653 | **2)** Split the input file `items.txt` such that the text before a line containing `colors` is part of the first file and the rest are part of the second file as shown below.
1654 |
1655 | ```bash
1656 | $ csplit -q items.txt '/colors/'
1657 |
1658 | $ head xx*
1659 | ==> xx00 <==
1660 | 1) fruits
1661 | apple 5
1662 | banana 10
1663 |
1664 | ==> xx01 <==
1665 | 2) colors
1666 | green
1667 | sky blue
1668 | 3) magical beasts
1669 | dragon 3
1670 | unicorn 42
1671 |
1672 | $ rm xx*
1673 | ```
1674 |
1675 | **3)** Split the input file `items.txt` such that the line containing `magical` and all the lines that come after are part of the single output file.
1676 |
1677 | ```bash
1678 | $ csplit -q items.txt '%magical%'
1679 |
1680 | $ cat xx00
1681 | 3) magical beasts
1682 | dragon 3
1683 | unicorn 42
1684 |
1685 | $ rm xx00
1686 | ```
1687 |
1688 | **4)** Split the input file `items.txt` such that the line containing `colors` as well the line that comes after are part of the first output file.
1689 |
1690 | ```bash
1691 | $ csplit -q items.txt '/colors/2'
1692 |
1693 | $ head xx*
1694 | ==> xx00 <==
1695 | 1) fruits
1696 | apple 5
1697 | banana 10
1698 | 2) colors
1699 | green
1700 |
1701 | ==> xx01 <==
1702 | sky blue
1703 | 3) magical beasts
1704 | dragon 3
1705 | unicorn 42
1706 |
1707 | $ rm xx*
1708 | ```
1709 |
1710 | **5)** Split the input file `items.txt` on the line that comes before a line containing `magical`. Generate only a single output file as shown below.
1711 |
1712 | ```bash
1713 | $ csplit -q items.txt '%magical%-1'
1714 |
1715 | $ cat xx00
1716 | sky blue
1717 | 3) magical beasts
1718 | dragon 3
1719 | unicorn 42
1720 |
1721 | $ rm xx00
1722 | ```
1723 |
1724 | **6)** Split the input file `blocks.txt` on the 4th occurrence of a line starting with the `-` character. Generate only a single output file as shown below.
1725 |
1726 | ```bash
1727 | $ csplit -q blocks.txt '%^-%' '{3}'
1728 |
1729 | $ cat xx00
1730 | ----
1731 | sky blue
1732 | dark green
1733 | ----
1734 | hi hello
1735 |
1736 | $ rm xx00
1737 | ```
1738 |
1739 | **7)** For the input file `blocks.txt`, determine the logic to produce the expected output shown below.
1740 |
1741 | ```bash
1742 | $ csplit -qz --suppress-matched blocks.txt '/----/' '{*}'
1743 |
1744 | $ head xx*
1745 | ==> xx00 <==
1746 | apple--banana
1747 | mango---fig
1748 |
1749 | ==> xx01 <==
1750 | 3.14
1751 | -42
1752 | 1000
1753 |
1754 | ==> xx02 <==
1755 | sky blue
1756 | dark green
1757 |
1758 | ==> xx03 <==
1759 | hi hello
1760 |
1761 | $ rm xx*
1762 | ```
1763 |
1764 | **8)** What does the `-k` option do?
1765 |
1766 | By default, `csplit` will remove the created output files if there's an error or a signal that causes the command to stop. You can use the `-k` option to keep such files. One use case is line number based splitting with the `{*}` modifier.
1767 |
1768 | ```bash
1769 | $ seq 7 | csplit -q - 4 '{*}'
1770 | csplit: ‘4’: line number out of range on repetition 1
1771 | $ ls xx*
1772 | ls: cannot access 'xx*': No such file or directory
1773 |
1774 | # -k option will allow you to retain the created files
1775 | $ seq 7 | csplit -qk - 4 '{*}'
1776 | csplit: ‘4’: line number out of range on repetition 1
1777 | $ head xx*
1778 | ==> xx00 <==
1779 | 1
1780 | 2
1781 | 3
1782 |
1783 | ==> xx01 <==
1784 | 4
1785 | 5
1786 | 6
1787 | 7
1788 |
1789 | $ rm xx*
1790 | ```
1791 |
1792 | **9)** Split the `books.txt` file on every line as shown below.
1793 |
1794 | ```bash
1795 | # can also use: split -l1 -d -a1 books.txt row_
1796 | $ csplit -qkz -f'row_' -n1 books.txt 1 '{*}'
1797 | csplit: ‘1’: line number out of range on repetition 3
1798 |
1799 | $ head row_*
1800 | ==> row_0 <==
1801 | Cradle:::Mage Errant::The Weirkey Chronicles
1802 |
1803 | ==> row_1 <==
1804 | Mother of Learning::Eight:::::Dear Spellbook:Ascendant
1805 |
1806 | ==> row_2 <==
1807 | Mark of the Fool:Super Powereds:::Ends of Magic
1808 |
1809 | $ rm row_*
1810 | ```
1811 |
1812 | **10)** Split the `items.txt` file on lines starting with a digit character. Matching lines shouldn't be part of the output and the files should be named `group_0.txt`, `group_1.txt` and so on.
1813 |
1814 | ```bash
1815 | $ csplit -qz --suppress-matched -q -f'group_' -b'%d.txt' items.txt '/^[0-9]/' '{*}'
1816 |
1817 | $ head group_*
1818 | ==> group_0.txt <==
1819 | apple 5
1820 | banana 10
1821 |
1822 | ==> group_1.txt <==
1823 | green
1824 | sky blue
1825 |
1826 | ==> group_2.txt <==
1827 | dragon 3
1828 | unicorn 42
1829 |
1830 | $ rm group_*
1831 | ```
1832 |
1833 |
1834 |
1835 | # expand and unexpand
1836 |
1837 | **1)** The `items.txt` file has space separated words. Convert the spaces to be aligned at 10 column widths as shown below.
1838 |
1839 | ```bash
1840 | $ cat items.txt
1841 | 1) fruits
1842 | apple 5
1843 | banana 10
1844 | 2) colors
1845 | green
1846 | sky blue
1847 | 3) magical beasts
1848 | dragon 3
1849 | unicorn 42
1850 |
1851 | $
1902 |
1903 | # basename and dirname
1904 |
1905 | **1)** Is the following command valid? If so, what would be the output?
1906 |
1907 | Yes, it is valid. Multiple slashes will be considered as a single slash. Any trailing slashes will be removed before determining the portion to be extracted.
1908 |
1909 | ```bash
1910 | $ basename -s.txt ~///test.txt///
1911 | test
1912 | ```
1913 |
1914 | **2)** Given the file path in the shell variable `p`, how'd you obtain the outputs shown below?
1915 |
1916 | ```bash
1917 | $ p='~/projects/square_tictactoe/python/game.py'
1918 | $ dirname $(dirname "$p")
1919 | ~/projects/square_tictactoe
1920 |
1921 | $ p='/backups/jan_2021.tar.gz'
1922 | $ dirname $(dirname "$p")
1923 | /
1924 | ```
1925 |
1926 | **3)** What would be the output of the `basename` command if the input has no leading directory component or only has the `/` character?
1927 |
1928 | If there's no leading directory component or if slash alone is the input, the argument will be returned as is after removing any trailing slashes.
1929 |
1930 | ```bash
1931 | $ basename filename.txt
1932 | filename.txt
1933 | $ basename /
1934 | /
1935 | ```
1936 |
1937 | **4)** For the paths stored in the shell variable `p`, how'd you obtain the outputs shown below?
1938 |
1939 | ```bash
1940 | $ p='/a/b/ip.txt /c/d/e/f/op.txt'
1941 |
1942 | # expected output 1
1943 | $ basename -s'.txt' $p
1944 | ip
1945 | op
1946 |
1947 | # expected output 2
1948 | $ dirname $p
1949 | /a/b
1950 | /c/d/e/f
1951 | ```
1952 |
1953 | **5)** Given the file path in the shell variable `p`, how'd you obtain the outputs shown below?
1954 |
1955 | ```bash
1956 | $ p='~/projects/python/square_tictactoe/game.py'
1957 | $ basename $(dirname "$p")
1958 | square_tictactoe
1959 |
1960 | $ p='/backups/aug_2024/ip.tar.gz'
1961 | $ basename $(dirname "$p")
1962 | aug_2024
1963 | ```
1964 |
1965 |
--------------------------------------------------------------------------------
/exercises/Exercises.md:
--------------------------------------------------------------------------------
1 | # Exercises
2 |
3 | > For solutions, see [Exercise_solutions.md](https://github.com/learnbyexample/cli_text_processing_coreutils/tree/main/exercises/Exercise_solutions.md).
4 |
5 |
6 |
7 | # cat and tac
8 |
9 | **1)** The given sample data has empty lines at the start and end of the input. Also, there are multiple empty lines between the paragraphs. How would you get the output shown below?
10 |
11 | ```bash
12 | # note that there's an empty line at the end of the output
13 | $ printf '\n\n\ndragon\n\n\n\nunicorn\nbee\n\n\n' | ##### add your solution here
14 |
15 | 1 dragon
16 |
17 | 2 unicorn
18 | 3 bee
19 |
20 | ```
21 |
22 | **2)** Pass appropriate arguments to the `cat` command to get the output shown below.
23 |
24 | ```bash
25 | $ cat greeting.txt
26 | Hi there
27 | Have a nice day
28 |
29 | $ echo '42 apples and 100 bananas' | cat ##### add your solution here
30 | 42 apples and 100 bananas
31 | Hi there
32 | Have a nice day
33 | ```
34 |
35 | **3)** What does the `-v` option of the `cat` command do?
36 |
37 | **4)** Which options of the `cat` command do the following stand in for?
38 |
39 | * `-e` option is equivalent to
40 | * `-t` option is equivalent to
41 | * `-A` option is equivalent to
42 |
43 | **5)** Will the two commands shown below produce the same output? If not, why not?
44 |
45 | ```bash
46 | $ cat fruits.txt ip.txt | tac
47 |
48 | $ tac fruits.txt ip.txt
49 | ```
50 |
51 | **6)** Reverse the contents of `blocks.txt` file as shown below, considering `----` as the separator.
52 |
53 | ```bash
54 | $ cat blocks.txt
55 | ----
56 | apple--banana
57 | mango---fig
58 | ----
59 | 3.14
60 | -42
61 | 1000
62 | ----
63 | sky blue
64 | dark green
65 | ----
66 | hi hello
67 |
68 | ##### add your solution here
69 | ----
70 | hi hello
71 | ----
72 | sky blue
73 | dark green
74 | ----
75 | 3.14
76 | -42
77 | 1000
78 | ----
79 | apple--banana
80 | mango---fig
81 | ```
82 |
83 | **7)** For the `blocks.txt` file, write solutions to display only the last such group and last two groups.
84 |
85 | ```bash
86 | ##### add your solution here
87 | ----
88 | hi hello
89 |
90 | ##### add your solution here
91 | ----
92 | sky blue
93 | dark green
94 | ----
95 | hi hello
96 | ```
97 |
98 | **8)** Reverse the contents of `items.txt` as shown below. Consider digits at the start of lines as the separator.
99 |
100 | ```bash
101 | $ cat items.txt
102 | 1) fruits
103 | apple 5
104 | banana 10
105 | 2) colors
106 | green
107 | sky blue
108 | 3) magical beasts
109 | dragon 3
110 | unicorn 42
111 |
112 | ##### add your solution here
113 | 3) magical beasts
114 | dragon 3
115 | unicorn 42
116 | 2) colors
117 | green
118 | sky blue
119 | 1) fruits
120 | apple 5
121 | banana 10
122 | ```
123 |
124 |
125 |
126 | # head and tail
127 |
128 | **1)** Use appropriate commands and shell features to get the output shown below.
129 |
130 | ```bash
131 | $ printf 'carpet\njeep\nbus\n'
132 | carpet
133 | jeep
134 | bus
135 |
136 | # use the above 'printf' command for input data
137 | $ c=##### add your solution here
138 | $ echo "$c"
139 | car
140 | ```
141 |
142 | **2)** How would you display all the input lines except the first one?
143 |
144 | ```bash
145 | $ printf 'apple\nfig\ncarpet\njeep\nbus\n' | ##### add your solution here
146 | fig
147 | carpet
148 | jeep
149 | bus
150 | ```
151 |
152 | **3)** Which command would you use to get the output shown below?
153 |
154 | ```bash
155 | $ cat fruits.txt
156 | banana
157 | papaya
158 | mango
159 | $ cat blocks.txt
160 | ----
161 | apple--banana
162 | mango---fig
163 | ----
164 | 3.14
165 | -42
166 | 1000
167 | ----
168 | sky blue
169 | dark green
170 | ----
171 | hi hello
172 |
173 | ##### add your solution here
174 | ==> fruits.txt <==
175 | banana
176 | papaya
177 |
178 | ==> blocks.txt <==
179 | ----
180 | apple--banana
181 | ```
182 |
183 | **4)** Use a combination of `head` and `tail` commands to get the 11th to 14th characters from the given input.
184 |
185 | ```bash
186 | $ printf 'apple\nfig\ncarpet\njeep\nbus\n' | ##### add your solution here
187 | carp
188 | ```
189 |
190 | **5)** Extract the starting six bytes from the input files `ip.txt` and `fruits.txt`.
191 |
192 | ```bash
193 | ##### add your solution here
194 | it is banana
195 | ```
196 |
197 | **6)** Extract the last six bytes from the input files `fruits.txt` and `ip.txt`.
198 |
199 | ```bash
200 | ##### add your solution here
201 | mango
202 | erish
203 | ```
204 |
205 | **7)** For the input file `ip.txt`, display except the last 5 lines.
206 |
207 | ```bash
208 | ##### add your solution here
209 | it is a warm and cozy day
210 | listen to what I say
211 | go play in the park
212 | come back before the sky turns dark
213 | ```
214 |
215 | **8)** Display the third line from the given `stdin` data. Consider the NUL character as the line separator.
216 |
217 | ```bash
218 | $ printf 'apple\0fig\0carpet\0jeep\0bus\0' | ##### add your solution here
219 | carpet
220 | ```
221 |
222 |
223 |
224 | # tr
225 |
226 | **1)** What's wrong with the following command?
227 |
228 | ```bash
229 | $ echo 'apple#banana#cherry' | tr # :
230 | ```
231 |
232 | **2)** Retain only alphabets, digits and whitespace characters.
233 |
234 | ```bash
235 | $ printf 'Apple_42 cool,blue\tDragon:army\n' | ##### add your solution here
236 | Apple42 coolblue Dragonarmy
237 | ```
238 |
239 | **3)** Similar to rot13, figure out a way to shift digits such that the same logic can be used both ways.
240 |
241 | ```bash
242 | $ echo '4780 89073' | ##### add your solution here
243 | 9235 34528
244 |
245 | $ echo '9235 34528' | ##### add your solution here
246 | 4780 89073
247 | ```
248 |
249 | **4)** Figure out the logic based on the given input and output data. Hint: use two ranges for the first set and only 6 characters in the second set.
250 |
251 | ```bash
252 | $ echo 'apple banana cherry damson etrog' | ##### add your solution here
253 | 1XXl5 21n1n1 3h5XXX 41mXon 5XXog
254 | ```
255 |
256 | **5)** Which option would you use to truncate the first set so that it matches the length of the second set?
257 |
258 | **6)** What does the `*` notation do in the second set?
259 |
260 | **7)** Change `:` to `-` and `;` to the newline character.
261 |
262 | ```bash
263 | $ echo 'tea:coffee;brown:teal;dragon:unicorn' | ##### add your solution here
264 | tea-coffee
265 | brown-teal
266 | dragon-unicorn
267 | ```
268 |
269 | **8)** Convert all characters to `*` except digit and newline characters.
270 |
271 | ```bash
272 | $ echo 'ajsd45_sdg2Khnf4v_54as' | ##### add your solution here
273 | ****45****2****4**54**
274 | ```
275 |
276 | **9)** Change consecutive repeated punctuation characters to a single punctuation character.
277 |
278 | ```bash
279 | $ echo '""hi..."", good morning!!!!' | ##### add your solution here
280 | "hi.", good morning!
281 | ```
282 |
283 | **10)** Figure out the logic based on the given input and output data.
284 |
285 | ```bash
286 | $ echo 'Aapple noon banana!!!!!' | ##### add your solution here
287 | :apple:noon:banana:
288 | ```
289 |
290 | **11)** The `books.txt` file has items separated by one or more `:` characters. Change this separator to a single newline character as shown below.
291 |
292 | ```bash
293 | $ cat books.txt
294 | Cradle:::Mage Errant::The Weirkey Chronicles
295 | Mother of Learning::Eight:::::Dear Spellbook:Ascendant
296 | Mark of the Fool:Super Powereds:::Ends of Magic
297 |
298 | ##### add your solution here
299 | Cradle
300 | Mage Errant
301 | The Weirkey Chronicles
302 | Mother of Learning
303 | Eight
304 | Dear Spellbook
305 | Ascendant
306 | Mark of the Fool
307 | Super Powereds
308 | Ends of Magic
309 | ```
310 |
311 |
312 |
313 | # cut
314 |
315 | **1)** Display only the third field.
316 |
317 | ```bash
318 | $ printf 'tea\tcoffee\tchocolate\tfruit\n' | ##### add your solution here
319 | chocolate
320 | ```
321 |
322 | **2)** Display the second and fifth fields. Consider `,` as the field separator.
323 |
324 | ```bash
325 | $ echo 'tea,coffee,chocolate,ice cream,fruit' | ##### add your solution here
326 | coffee,fruit
327 | ```
328 |
329 | **3)** Why does the below command not work as expected? What other tools can you use in such cases?
330 |
331 | ```bash
332 | # not working as expected
333 | $ echo 'apple,banana,cherry,fig' | cut -d, -f3,1,3
334 | apple,cherry
335 |
336 | # expected output
337 | $ echo 'apple,banana,cherry,fig' | ##### add your solution here
338 | cherry,apple,cherry
339 | ```
340 |
341 | **4)** Display except the second field in the format shown below. Can you construct two different solutions?
342 |
343 | ```bash
344 | # solution 1
345 | $ echo 'apple,banana,cherry,fig' | ##### add your solution here
346 | apple cherry fig
347 |
348 | # solution 2
349 | $ echo '2,3,4,5,6,7,8' | ##### add your solution here
350 | 2 4 5 6 7 8
351 | ```
352 |
353 | **5)** Extract the first three characters from the input lines as shown below. Can you also use the `head` command for this purpose? If not, why not?
354 |
355 | ```bash
356 | $ printf 'apple\nbanana\ncherry\nfig\n' | ##### add your solution here
357 | app
358 | ban
359 | che
360 | fig
361 | ```
362 |
363 | **6)** Display only the first and third fields of the `scores.csv` input file, with tab as the output field separator.
364 |
365 | ```bash
366 | $ cat scores.csv
367 | Name,Maths,Physics,Chemistry
368 | Ith,100,100,100
369 | Cy,97,98,95
370 | Lin,78,83,80
371 |
372 | ##### add your solution here
373 | Name Physics
374 | Ith 100
375 | Cy 98
376 | Lin 83
377 | ```
378 |
379 | **7)** The given input data uses one or more `:` characters as the field separator. Assume that no field content will have the `:` character. Display except the second field, with ` : ` as the output field separator.
380 |
381 | ```bash
382 | $ cat books.txt
383 | Cradle:::Mage Errant::The Weirkey Chronicles
384 | Mother of Learning::Eight:::::Dear Spellbook:Ascendant
385 | Mark of the Fool:Super Powereds:::Ends of Magic
386 |
387 | ##### add your solution here
388 | Cradle : The Weirkey Chronicles
389 | Mother of Learning : Dear Spellbook : Ascendant
390 | Mark of the Fool : Ends of Magic
391 | ```
392 |
393 | **8)** Which option would you use to not display lines that do not contain the input delimiter character?
394 |
395 | **9)** Modify the command to get the expected output shown below.
396 |
397 | ```bash
398 | $ printf 'apple\nbanana\ncherry\n' | cut -c-3 --output-delimiter=:
399 | app
400 | ban
401 | che
402 |
403 | $ printf 'apple\nbanana\ncherry\n' | ##### add your solution here
404 | a:p:p
405 | b:a:n
406 | c:h:e
407 | ```
408 |
409 | **10)** Figure out the logic based on the given input and output data.
410 |
411 | ```bash
412 | $ printf 'apple\0fig\0carpet\0jeep\0' | ##### add your solution here | cat -v
413 | ple^@g^@rpet^@ep^@
414 | ```
415 |
416 |
417 |
418 | # seq
419 |
420 | **1)** Generate numbers from `42` to `45` in ascending order.
421 |
422 | ```bash
423 | ##### add your solution here
424 | 42
425 | 43
426 | 44
427 | 45
428 | ```
429 |
430 | **2)** Why does the command shown below produce no output?
431 |
432 | ```bash
433 | # no output
434 | $ seq 45 42
435 |
436 | # expected output
437 | ##### add your solution here
438 | 45
439 | 44
440 | 43
441 | 42
442 | ```
443 |
444 | **3)** Generate numbers from `25` to `10` in descending order, with a step value of `5`.
445 |
446 | ```bash
447 | ##### add your solution here
448 | 25
449 | 20
450 | 15
451 | 10
452 | ```
453 |
454 | **4)** Is the sequence shown below possible to generate with `seq`? If so, how?
455 |
456 | ```bash
457 | ##### add your solution here
458 | 01.5,02.5,03.5,04.5,05.5
459 | ```
460 |
461 | **5)** Modify the command shown below to customize the output numbering format.
462 |
463 | ```bash
464 | $ seq 30.14 3.36 40.72
465 | 30.14
466 | 33.50
467 | 36.86
468 | 40.22
469 |
470 | ##### add your solution here
471 | 3.014e+01
472 | 3.350e+01
473 | 3.686e+01
474 | 4.022e+01
475 | ```
476 |
477 |
478 |
479 | # shuf
480 |
481 | **1)** What's wrong with the given command?
482 |
483 | ```bash
484 | $ shuf --random-source=greeting.txt fruits.txt books.txt
485 | shuf: extra operand ‘books.txt’
486 | Try 'shuf --help' for more information.
487 |
488 | # expected output
489 | ##### add your solution here
490 | banana
491 | Cradle:::Mage Errant::The Weirkey Chronicles
492 | Mother of Learning::Eight:::::Dear Spellbook:Ascendant
493 | papaya
494 | Mark of the Fool:Super Powereds:::Ends of Magic
495 | mango
496 | ```
497 |
498 | **2)** What do the `-r` and `-n` options do? Why are they often used together?
499 |
500 | **3)** What does the following command do?
501 |
502 | ```bash
503 | $ shuf -e apple banana cherry fig mango
504 | ```
505 |
506 | **4)** Which option would you use to generate random numbers? Given an example.
507 |
508 | **5)** How would you generate 5 random numbers between `0.125` and `0.789` with a step value of `0.023`?
509 |
510 | ```bash
511 | # output shown below is a sample, might differ for you
512 | ##### add your solution here
513 | 0.378
514 | 0.631
515 | 0.447
516 | 0.746
517 | 0.723
518 | ```
519 |
520 |
521 |
522 | # paste
523 |
524 | **1)** What's the default delimiter character added by the `paste` command? Which option would you use to customize this separator?
525 |
526 | **2)** Will the following two commands produce equivalent output? If not, why not?
527 |
528 | ```bash
529 | $ paste -d, <(seq 3) <(printf '%s\n' item_{1..3})
530 |
531 | $ printf '%s\n' {1..3},item_{1..3}
532 | ```
533 |
534 | **3)** Combine the two data sources as shown below.
535 |
536 | ```bash
537 | $ printf '1)\n2)\n3)'
538 | 1)
539 | 2)
540 | 3)
541 | $ cat fruits.txt
542 | banana
543 | papaya
544 | mango
545 |
546 | ##### add your solution here
547 | 1)banana
548 | 2)papaya
549 | 3)mango
550 | ```
551 |
552 | **4)** Interleave the contents of `fruits.txt` and `books.txt`.
553 |
554 | ```bash
555 | ##### add your solution here
556 | banana
557 | Cradle:::Mage Errant::The Weirkey Chronicles
558 | papaya
559 | Mother of Learning::Eight:::::Dear Spellbook:Ascendant
560 | mango
561 | Mark of the Fool:Super Powereds:::Ends of Magic
562 | ```
563 |
564 | **5)** Generate numbers `1` to `9` in two different formats as shown below.
565 |
566 | ```bash
567 | ##### add your solution here
568 | 1:2:3
569 | 4:5:6
570 | 7:8:9
571 |
572 | ##### add your solution here
573 | 1 : 4 : 7
574 | 2 : 5 : 8
575 | 3 : 6 : 9
576 | ```
577 |
578 | **6)** Combine the contents of `fruits.txt` and `colors.txt` as shown below.
579 |
580 | ```bash
581 | $ cat fruits.txt
582 | banana
583 | papaya
584 | mango
585 | $ cat colors.txt
586 | deep blue
587 | light orange
588 | blue delight
589 |
590 | ##### add your solution here
591 | banana,deep blue,papaya,light orange,mango,blue delight
592 | ```
593 |
594 |
595 |
596 | # pr
597 |
598 | **1)** What does the `-t` option do?
599 |
600 | **2)** Generate numbers `1` to `16` in two different formats as shown below.
601 |
602 | ```bash
603 | $ seq -w 16 | ##### add your solution here
604 | 01,02,03,04
605 | 05,06,07,08
606 | 09,10,11,12
607 | 13,14,15,16
608 |
609 | $ seq -w 16 | ##### add your solution here
610 | 01,05,09,13
611 | 02,06,10,14
612 | 03,07,11,15
613 | 04,08,12,16
614 | ```
615 |
616 | **3)** How'd you solve the issue shown below?
617 |
618 | ```bash
619 | $ seq 100 | pr -37ats,
620 | pr: page width too narrow
621 | ```
622 |
623 | **4)** Combine the contents of `fruits.txt` and `colors.txt` in two different formats as shown below.
624 |
625 | ```bash
626 | $ cat fruits.txt
627 | banana
628 | papaya
629 | mango
630 | $ cat colors.txt
631 | deep blue
632 | light orange
633 | blue delight
634 |
635 | ##### add your solution here
636 | banana : deep blue
637 | papaya : light orange
638 | mango : blue delight
639 |
640 | ##### add your solution here
641 | 1:banana,deep blue
642 | 2:papaya,light orange
643 | 3:mango,blue delight
644 | ```
645 |
646 | **5)** What does the `-d` option do?
647 |
648 |
649 |
650 | # fold and fmt
651 |
652 | **1)** What's the default wrap length of the `fold` and `fmt` commands?
653 |
654 | **2)** Fold the given `stdin` data at 9 bytes.
655 |
656 | ```bash
657 | $ echo 'hi hello, how are you?' | ##### add your solution here
658 | hi hello,
659 | how are
660 | you?
661 | ```
662 |
663 | **3)** Figure out the logic based on the given input and output data using the `fold` command.
664 |
665 | ```bash
666 | $ cat ip.txt
667 | it is a warm and cozy day
668 | listen to what I say
669 | go play in the park
670 | come back before the sky turns dark
671 |
672 | There are so many delights to cherish
673 | Apple, Banana and Cherry
674 | Bread, Butter and Jelly
675 | Try them all before you perish
676 |
677 | ##### add your solution here
678 | it is a
679 | warm and
680 | cozy day
681 | listen to
682 | what I say
683 | ```
684 |
685 | **4)** What does the `fold -b` option do?
686 |
687 | **5)** How'd you get the expected output shown below?
688 |
689 | ```bash
690 | # wrong output
691 | $ echo 'fig appleseed mango pomegranate' | fold -sw7
692 | fig
693 | applese
694 | ed
695 | mango
696 | pomegra
697 | nate
698 |
699 | # expected output
700 | $ echo 'fig appleseed mango pomegranate' | ##### add your solution here
701 | fig
702 | appleseed
703 | mango
704 | pomegranate
705 | ```
706 |
707 | **6)** What do the options `-s` and `-u` of the `fmt` command do?
708 |
709 |
710 |
711 | # sort
712 |
713 | **1)** Default `sort` doesn't work for numbers. Which option would you use to get the expected output shown below?
714 |
715 | ```bash
716 | $ printf '100\n10\n20\n3000\n2.45\n' | sort ##### add your solution here
717 | 2.45
718 | 10
719 | 20
720 | 100
721 | 3000
722 | ```
723 |
724 | **2)** Which `sort` option will help you ignore case? `LC_ALL=C` is used here to avoid differences due to locale.
725 |
726 | ```bash
727 | $ printf 'Super\nover\nRUNE\ntea\n' | LC_ALL=C sort ##### add your solution here
728 | over
729 | RUNE
730 | Super
731 | tea
732 | ```
733 |
734 | **3)** The `-n` option doesn't work for all sorts of numbers. Which `sort` option would you use to get the expected output shown below?
735 |
736 | ```bash
737 | # wrong output
738 | $ printf '+120\n-1.53\n3.14e+4\n42.1e-2' | sort -n
739 | -1.53
740 | +120
741 | 3.14e+4
742 | 42.1e-2
743 |
744 | # expected output
745 | $ printf '+120\n-1.53\n3.14e+4\n42.1e-2' | sort ##### add your solution here
746 | -1.53
747 | 42.1e-2
748 | +120
749 | 3.14e+4
750 | ```
751 |
752 | **4)** What do the `-V` and `-h` options do?
753 |
754 | **5)** Is there a difference between `shuf` and `sort -R`?
755 |
756 | **6)** Sort the `scores.csv` file numerically in ascending order using the contents of the second field. Header line should be preserved as the first line as shown below.
757 |
758 | ```bash
759 | $ cat scores.csv
760 | Name,Maths,Physics,Chemistry
761 | Ith,100,100,100
762 | Cy,97,98,95
763 | Lin,78,83,80
764 |
765 | ##### add your solution here
766 | Name,Maths,Physics,Chemistry
767 | Lin,78,83,80
768 | Cy,97,98,95
769 | Ith,100,100,100
770 | ```
771 |
772 | **7)** Sort the contents of `duplicates.csv` by the fourth column numbers in descending order. Retain only the first copy of lines with the same number.
773 |
774 | ```bash
775 | $ cat duplicates.csv
776 | brown,toy,bread,42
777 | dark red,ruby,rose,111
778 | blue,ruby,water,333
779 | dark red,sky,rose,555
780 | yellow,toy,flower,333
781 | white,sky,bread,111
782 | light red,purse,rose,333
783 |
784 | ##### add your solution here
785 | dark red,sky,rose,555
786 | blue,ruby,water,333
787 | dark red,ruby,rose,111
788 | brown,toy,bread,42
789 | ```
790 |
791 | **8)** Sort the contents of `duplicates.csv` by the third column item. Use the fourth column numbers as the tie-breaker.
792 |
793 | ```bash
794 | ##### add your solution here
795 | brown,toy,bread,42
796 | white,sky,bread,111
797 | yellow,toy,flower,333
798 | dark red,ruby,rose,111
799 | light red,purse,rose,333
800 | dark red,sky,rose,555
801 | blue,ruby,water,333
802 | ```
803 |
804 | **9)** What does the `-s` option provide?
805 |
806 | **10)** Sort the given input based on the numbers inside the brackets.
807 |
808 | ```bash
809 | $ printf '(-3.14)\n[45]\n(12.5)\n{14093}' | ##### add your solution here
810 | (-3.14)
811 | (12.5)
812 | [45]
813 | {14093}
814 | ```
815 |
816 | **11)** What do the `-c`, `-C` and `-m` options do?
817 |
818 |
819 |
820 | # uniq
821 |
822 | **1)** Will `uniq` throw an error if the input is not sorted? What do you think will be the output for the following input?
823 |
824 | ```bash
825 | $ printf 'red\nred\nred\ngreen\nred\nblue\nblue' | uniq
826 | ```
827 |
828 | **2)** Are there differences between `sort -u file` and `sort file | uniq`?
829 |
830 | **3)** What are the differences between `sort -u` and `uniq -u` options, if any?
831 |
832 | **4)** Filter the third column items from `duplicates.csv`. Construct three solutions to display only unique items, duplicate items and all duplicates.
833 |
834 | ```bash
835 | $ cat duplicates.csv
836 | brown,toy,bread,42
837 | dark red,ruby,rose,111
838 | blue,ruby,water,333
839 | dark red,sky,rose,555
840 | yellow,toy,flower,333
841 | white,sky,bread,111
842 | light red,purse,rose,333
843 |
844 | # unique
845 | ##### add your solution here
846 | flower
847 | water
848 |
849 | # duplicates
850 | ##### add your solution here
851 | bread
852 | rose
853 |
854 | # all duplicates
855 | ##### add your solution here
856 | bread
857 | bread
858 | rose
859 | rose
860 | rose
861 | ```
862 |
863 | **5)** What does the `--group` option do? What customization features are available?
864 |
865 | **6)** Count the number of times input lines are repeated and display the results in the format shown below.
866 |
867 | ```bash
868 | $ s='brown\nbrown\nbrown\ngreen\nbrown\nblue\nblue'
869 | $ printf '%b' "$s" | ##### add your solution here
870 | 1 green
871 | 2 blue
872 | 4 brown
873 | ```
874 |
875 | **7)** For the input file `f1.txt`, retain only unique entries based on the first two characters of each line. For example, `abcd` and `ab12` should be considered as duplicates and neither of them will be part of the output.
876 |
877 | ```bash
878 | $ cat f1.txt
879 | 3) cherry
880 | 1) apple
881 | 2) banana
882 | 1) almond
883 | 4) mango
884 | 2) berry
885 | 3) chocolate
886 | 1) apple
887 | 5) cherry
888 |
889 | ##### add your solution here
890 | 4) mango
891 | 5) cherry
892 | ```
893 |
894 | **8)** For the input file `f1.txt`, display only the duplicate items without considering the first two characters of each line. For example, `abcd` and `12cd` should be considered as duplicates. Assume that the third character of each line is always a space character.
895 |
896 | ```bash
897 | ##### add your solution here
898 | 1) apple
899 | 3) cherry
900 | ```
901 |
902 | **9)** What does the `-s` option do?
903 |
904 | **10)** Filter only unique lines, but ignore differences due to case.
905 |
906 | ```bash
907 | $ printf 'cat\nbat\nCAT\nCar\nBat\nmat\nMat' | ##### add your solution here
908 | Car
909 | ```
910 |
911 |
912 |
913 | # comm
914 |
915 | **1)** Get the common lines between the `s1.txt` and `s2.txt` files. Assume that their contents are already sorted.
916 |
917 | ```bash
918 | $ paste s1.txt s2.txt
919 | apple banana
920 | coffee coffee
921 | fig eclair
922 | honey fig
923 | mango honey
924 | pasta milk
925 | sugar tea
926 | tea yeast
927 |
928 | ##### add your solution here
929 | coffee
930 | fig
931 | honey
932 | tea
933 | ```
934 |
935 | **2)** Display lines present in `s1.txt` but not `s2.txt` and vice versa.
936 |
937 | ```bash
938 | # lines unique to the first file
939 | ##### add your solution here
940 | apple
941 | mango
942 | pasta
943 | sugar
944 |
945 | # lines unique to the second file
946 | ##### add your solution here
947 | banana
948 | eclair
949 | milk
950 | yeast
951 | ```
952 |
953 | **3)** Display lines unique to the `s1.txt` file and the common lines when compared to the `s2.txt` file. Use `==>` to separate the output columns.
954 |
955 | ```bash
956 | ##### add your solution here
957 | apple
958 | ==>coffee
959 | ==>fig
960 | ==>honey
961 | mango
962 | pasta
963 | sugar
964 | ==>tea
965 | ```
966 |
967 | **4)** What does the `--total` option do?
968 |
969 | **5)** Will the `comm` command fail if there are repeated lines in the input files? If not, what'd be the expected output for the command shown below?
970 |
971 | ```bash
972 | $ cat s3.txt
973 | apple
974 | apple
975 | guava
976 | honey
977 | tea
978 | tea
979 | tea
980 |
981 | $ comm -23 s3.txt s1.txt
982 | ```
983 |
984 |
985 |
986 | # join
987 |
988 | > Assume that the input files are already sorted for these exercises.
989 |
990 | **1)** Use appropriate options to get the expected outputs shown below.
991 |
992 | ```bash
993 | # no output
994 | $ join <(printf 'apple 2\nfig 5') <(printf 'Fig 10\nmango 4')
995 |
996 | # expected output 1
997 | ##### add your solution here
998 | fig 5 10
999 |
1000 | # expected output 2
1001 | ##### add your solution here
1002 | apple 2
1003 | fig 5 10
1004 | mango 4
1005 | ```
1006 |
1007 | **2)** Use the `join` command to display only the non-matching lines based on the first field.
1008 |
1009 | ```bash
1010 | $ cat j1.txt
1011 | apple 2
1012 | fig 5
1013 | lemon 10
1014 | tomato 22
1015 | $ cat j2.txt
1016 | almond 33
1017 | fig 115
1018 | mango 20
1019 | pista 42
1020 |
1021 | # first field items present in j1.txt but not j2.txt
1022 | ##### add your solution here
1023 | apple 2
1024 | lemon 10
1025 | tomato 22
1026 |
1027 | # first field items present in j2.txt but not j1.txt
1028 | ##### add your solution here
1029 | almond 33
1030 | mango 20
1031 | pista 42
1032 | ```
1033 |
1034 | **3)** Filter lines from `j1.txt` and `j2.txt` that match the items from `s1.txt`.
1035 |
1036 | ```bash
1037 | $ cat s1.txt
1038 | apple
1039 | coffee
1040 | fig
1041 | honey
1042 | mango
1043 | pasta
1044 | sugar
1045 | tea
1046 |
1047 | ##### add your solution here
1048 | apple 2
1049 | fig 115
1050 | fig 5
1051 | mango 20
1052 | ```
1053 |
1054 | **4)** Join the `marks_1.csv` and `marks_2.csv` files to get the expected output shown below.
1055 |
1056 | ```bash
1057 | $ cat marks_1.csv
1058 | Name,Biology,Programming
1059 | Er,92,77
1060 | Ith,100,100
1061 | Lin,92,100
1062 | Sil,86,98
1063 | $ cat marks_2.csv
1064 | Name,Maths,Physics,Chemistry
1065 | Cy,97,98,95
1066 | Ith,100,100,100
1067 | Lin,78,83,80
1068 |
1069 | ##### add your solution here
1070 | Name,Biology,Programming,Maths,Physics,Chemistry
1071 | Ith,100,100,100,100,100
1072 | Lin,92,100,78,83,80
1073 | ```
1074 |
1075 | **5)** By default, the first field is used to combine the lines. Which options are helpful if you want to change the key field to be used for joining?
1076 |
1077 | **6)** Join the `marks_1.csv` and `marks_2.csv` files to get the expected output with specific fields as shown below.
1078 |
1079 | ```bash
1080 | ##### add your solution here
1081 | Name,Programming,Maths,Biology
1082 | Ith,100,100,100
1083 | Lin,100,78,92
1084 | ```
1085 |
1086 | **7)** Join the `marks_1.csv` and `marks_2.csv` files to get the expected output shown below. Use `50` as the filler data.
1087 |
1088 | ```bash
1089 | ##### add your solution here
1090 | Name,Biology,Programming,Maths,Physics,Chemistry
1091 | Cy,50,50,97,98,95
1092 | Er,92,77,50,50,50
1093 | Ith,100,100,100,100,100
1094 | Lin,92,100,78,83,80
1095 | Sil,86,98,50,50,50
1096 | ```
1097 |
1098 | **8)** When you use the `-o auto` option, what'd happen to the extra fields compared to those in the first lines of the input data?
1099 |
1100 | **9)** From the input files `j3.txt` and `j4.txt`, filter only the lines are unique — i.e. lines that are not common to these files. Assume that the input files do not have duplicate entries.
1101 |
1102 | ```bash
1103 | $ cat j3.txt
1104 | almond
1105 | apple pie
1106 | cold coffee
1107 | honey
1108 | mango shake
1109 | pasta
1110 | sugar
1111 | tea
1112 | $ cat j4.txt
1113 | apple
1114 | banana shake
1115 | coffee
1116 | fig
1117 | honey
1118 | mango shake
1119 | milk
1120 | tea
1121 | yeast
1122 |
1123 | ##### add your solution here
1124 | almond
1125 | apple
1126 | apple pie
1127 | banana shake
1128 | coffee
1129 | cold coffee
1130 | fig
1131 | milk
1132 | pasta
1133 | sugar
1134 | yeast
1135 | ```
1136 |
1137 | **10)** From the input files `j3.txt` and `j4.txt`, filter only the lines are common to these files.
1138 |
1139 | ```bash
1140 | ##### add your solution here
1141 | honey
1142 | mango shake
1143 | tea
1144 | ```
1145 |
1146 |
1147 |
1148 | # nl
1149 |
1150 | **1)** `nl` and `cat -n` are always equivalent for numbering lines. True or False?
1151 |
1152 | **2)** What does the `-n` option do?
1153 |
1154 | **3)** Use `nl` to produce the two expected outputs shown below.
1155 |
1156 | ```bash
1157 | $ cat greeting.txt
1158 | Hi there
1159 | Have a nice day
1160 |
1161 | # expected output 1
1162 | ##### add your solution here
1163 | 001 Hi there
1164 | 002 Have a nice day
1165 |
1166 | # expected output 2
1167 | ##### add your solution here
1168 | 001) Hi there
1169 | 002) Have a nice day
1170 | ```
1171 |
1172 | **4)** Figure out the logic based on the given input and output data.
1173 |
1174 | ```bash
1175 | $ cat s1.txt
1176 | apple
1177 | coffee
1178 | fig
1179 | honey
1180 | mango
1181 | pasta
1182 | sugar
1183 | tea
1184 |
1185 | ##### add your solution here
1186 | 15. apple
1187 | 13. coffee
1188 | 11. fig
1189 | 9. honey
1190 | 7. mango
1191 | 5. pasta
1192 | 3. sugar
1193 | 1. tea
1194 | ```
1195 |
1196 | **5)** What are the three types of sections supported by `nl`?
1197 |
1198 | **6)** Only number the lines that start with `----` in the format shown below.
1199 |
1200 | ```bash
1201 | $ cat blocks.txt
1202 | ----
1203 | apple--banana
1204 | mango---fig
1205 | ----
1206 | 3.14
1207 | -42
1208 | 1000
1209 | ----
1210 | sky blue
1211 | dark green
1212 | ----
1213 | hi hello
1214 |
1215 | ##### add your solution here
1216 | 1) ----
1217 | apple--banana
1218 | mango---fig
1219 | 2) ----
1220 | 3.14
1221 | -42
1222 | 1000
1223 | 3) ----
1224 | sky blue
1225 | dark green
1226 | 4) ----
1227 | hi hello
1228 | ```
1229 |
1230 | **7)** For the `blocks.txt` file, determine the logic to produce the expected output shown below.
1231 |
1232 | ```bash
1233 | ##### add your solution here
1234 |
1235 | 1. apple--banana
1236 | 2. mango---fig
1237 |
1238 | 1. 3.14
1239 | 2. -42
1240 | 3. 1000
1241 |
1242 | 1. sky blue
1243 | 2. dark green
1244 |
1245 | 1. hi hello
1246 | ```
1247 |
1248 | **8)** What does the `-l` option do?
1249 |
1250 | **9)** Figure out the logic based on the given input and output data.
1251 |
1252 | ```bash
1253 | $ cat all_sections.txt
1254 | \:\:\:
1255 | Header
1256 | teal
1257 | \:\:
1258 | Hi there
1259 | How are you
1260 | \:\:
1261 | banana
1262 | papaya
1263 | mango
1264 | \:
1265 | Footer
1266 |
1267 | ##### add your solution here
1268 |
1269 | 1) Header
1270 | 2) teal
1271 |
1272 | 3) Hi there
1273 | 4) How are you
1274 |
1275 | 5) banana
1276 | 6) papaya
1277 | 7) mango
1278 |
1279 | Footer
1280 | ```
1281 |
1282 |
1283 |
1284 | # wc
1285 |
1286 | **1)** Save the number of lines in the `greeting.txt` input file to the `lines` shell variable.
1287 |
1288 | ```bash
1289 | $ lines=##### add your solution here
1290 | $ echo "$lines"
1291 | 2
1292 | ```
1293 |
1294 | **2)** What do you think will be the output of the following command?
1295 |
1296 | ```bash
1297 | $ echo 'dragons:2 ; unicorns:10' | wc -w
1298 | ```
1299 |
1300 | **3)** Use appropriate options and arguments to get the output as shown below. Also, why is the line count showing as `2` instead of `3` for the `stdin` data?
1301 |
1302 | ```bash
1303 | $ printf 'apple\nbanana\ncherry' | ##### add your solution here
1304 | 2 25 greeting.txt
1305 | 2 19 -
1306 | 4 44 total
1307 | ```
1308 |
1309 | **4)** Use appropriate options and arguments to get the output shown below.
1310 |
1311 | ```bash
1312 | $ printf 'greeting.txt\0scores.csv' | ##### add your solution here
1313 | 2 6 25 greeting.txt
1314 | 4 4 70 scores.csv
1315 | 6 10 95 total
1316 | ```
1317 |
1318 | **5)** What is the difference between `wc -c` and `wc -m` options? And which option would you use to get the longest line length?
1319 |
1320 | **6)** Calculate the number of comma separated words from the `scores.csv` file.
1321 |
1322 | ```bash
1323 | $ cat scores.csv
1324 | Name,Maths,Physics,Chemistry
1325 | Ith,100,100,100
1326 | Cy,97,98,95
1327 | Lin,78,83,80
1328 |
1329 | ##### add your solution here
1330 | 16
1331 | ```
1332 |
1333 |
1334 |
1335 | # split
1336 |
1337 | > Remove the output files after every exercise.
1338 |
1339 | **1)** Split the `s1.txt` file 3 lines at a time.
1340 |
1341 | ```bash
1342 | ##### add your solution here
1343 |
1344 | $ head xa?
1345 | ==> xaa <==
1346 | apple
1347 | coffee
1348 | fig
1349 |
1350 | ==> xab <==
1351 | honey
1352 | mango
1353 | pasta
1354 |
1355 | ==> xac <==
1356 | sugar
1357 | tea
1358 |
1359 | $ rm xa?
1360 | ```
1361 |
1362 | **2)** Use appropriate options to get the output shown below.
1363 |
1364 | ```bash
1365 | $ echo 'apple,banana,cherry,dates' | ##### add your solution here
1366 |
1367 | $ head xa?
1368 | ==> xaa <==
1369 | apple,
1370 | ==> xab <==
1371 | banana,
1372 | ==> xac <==
1373 | cherry,
1374 | ==> xad <==
1375 | dates
1376 |
1377 | $ rm xa?
1378 | ```
1379 |
1380 | **3)** What do the `-b` and `-C` options do?
1381 |
1382 | **4)** Display the 2nd chunk of the `ip.txt` file after splitting it 4 times as shown below.
1383 |
1384 | ```bash
1385 | ##### add your solution here
1386 | come back before the sky turns dark
1387 |
1388 | There are so many delights to cherish
1389 | ```
1390 |
1391 | **5)** What does the `r` prefix do when used with the `-n` option?
1392 |
1393 | **6)** Split the `ip.txt` file 2 lines at a time. Customize the output filenames as shown below.
1394 |
1395 | ```bash
1396 | ##### add your solution here
1397 |
1398 | $ head ip_*
1399 | ==> ip_0.txt <==
1400 | it is a warm and cozy day
1401 | listen to what I say
1402 |
1403 | ==> ip_1.txt <==
1404 | go play in the park
1405 | come back before the sky turns dark
1406 |
1407 | ==> ip_2.txt <==
1408 |
1409 | There are so many delights to cherish
1410 |
1411 | ==> ip_3.txt <==
1412 | Apple, Banana and Cherry
1413 | Bread, Butter and Jelly
1414 |
1415 | ==> ip_4.txt <==
1416 | Try them all before you perish
1417 |
1418 | $ rm ip_*
1419 | ```
1420 |
1421 | **7)** Which option would you use to prevent empty files in the output?
1422 |
1423 | **8)** Split the `items.txt` file 5 lines at a time. Additionally, remove lines starting with a digit character as shown below.
1424 |
1425 | ```bash
1426 | $ cat items.txt
1427 | 1) fruits
1428 | apple 5
1429 | banana 10
1430 | 2) colors
1431 | green
1432 | sky blue
1433 | 3) magical beasts
1434 | dragon 3
1435 | unicorn 42
1436 |
1437 | ##### add your solution here
1438 |
1439 | $ head xa?
1440 | ==> xaa <==
1441 | apple 5
1442 | banana 10
1443 | green
1444 |
1445 | ==> xab <==
1446 | sky blue
1447 | dragon 3
1448 | unicorn 42
1449 |
1450 | $ rm xa?
1451 | ```
1452 |
1453 |
1454 |
1455 | # csplit
1456 |
1457 | > Remove the output files after every exercise.
1458 |
1459 | **1)** Split the `blocks.txt` file such that the first 7 lines are in the first file and the rest are in the second file as shown below.
1460 |
1461 | ```bash
1462 | ##### add your solution here
1463 |
1464 | $ head xx*
1465 | ==> xx00 <==
1466 | ----
1467 | apple--banana
1468 | mango---fig
1469 | ----
1470 | 3.14
1471 | -42
1472 | 1000
1473 |
1474 | ==> xx01 <==
1475 | ----
1476 | sky blue
1477 | dark green
1478 | ----
1479 | hi hello
1480 |
1481 | $ rm xx*
1482 | ```
1483 |
1484 | **2)** Split the input file `items.txt` such that the text before a line containing `colors` is part of the first file and the rest are part of the second file as shown below.
1485 |
1486 | ```bash
1487 | ##### add your solution here
1488 |
1489 | $ head xx*
1490 | ==> xx00 <==
1491 | 1) fruits
1492 | apple 5
1493 | banana 10
1494 |
1495 | ==> xx01 <==
1496 | 2) colors
1497 | green
1498 | sky blue
1499 | 3) magical beasts
1500 | dragon 3
1501 | unicorn 42
1502 |
1503 | $ rm xx*
1504 | ```
1505 |
1506 | **3)** Split the input file `items.txt` such that the line containing `magical` and all the lines that come after are part of the single output file.
1507 |
1508 | ```bash
1509 | ##### add your solution here
1510 |
1511 | $ cat xx00
1512 | 3) magical beasts
1513 | dragon 3
1514 | unicorn 42
1515 |
1516 | $ rm xx00
1517 | ```
1518 |
1519 | **4)** Split the input file `items.txt` such that the line containing `colors` as well the line that comes after are part of the first output file.
1520 |
1521 | ```bash
1522 | ##### add your solution here
1523 |
1524 | $ head xx*
1525 | ==> xx00 <==
1526 | 1) fruits
1527 | apple 5
1528 | banana 10
1529 | 2) colors
1530 | green
1531 |
1532 | ==> xx01 <==
1533 | sky blue
1534 | 3) magical beasts
1535 | dragon 3
1536 | unicorn 42
1537 |
1538 | $ rm xx*
1539 | ```
1540 |
1541 | **5)** Split the input file `items.txt` on the line that comes before a line containing `magical`. Generate only a single output file as shown below.
1542 |
1543 | ```bash
1544 | ##### add your solution here
1545 |
1546 | $ cat xx00
1547 | sky blue
1548 | 3) magical beasts
1549 | dragon 3
1550 | unicorn 42
1551 |
1552 | $ rm xx00
1553 | ```
1554 |
1555 | **6)** Split the input file `blocks.txt` on the 4th occurrence of a line starting with the `-` character. Generate only a single output file as shown below.
1556 |
1557 | ```bash
1558 | ##### add your solution here
1559 |
1560 | $ cat xx00
1561 | ----
1562 | sky blue
1563 | dark green
1564 | ----
1565 | hi hello
1566 |
1567 | $ rm xx00
1568 | ```
1569 |
1570 | **7)** For the input file `blocks.txt`, determine the logic to produce the expected output shown below.
1571 |
1572 | ```bash
1573 | ##### add your solution here
1574 |
1575 | $ head xx*
1576 | ==> xx00 <==
1577 | apple--banana
1578 | mango---fig
1579 |
1580 | ==> xx01 <==
1581 | 3.14
1582 | -42
1583 | 1000
1584 |
1585 | ==> xx02 <==
1586 | sky blue
1587 | dark green
1588 |
1589 | ==> xx03 <==
1590 | hi hello
1591 |
1592 | $ rm xx*
1593 | ```
1594 |
1595 | **8)** What does the `-k` option do?
1596 |
1597 | **9)** Split the `books.txt` file on every line as shown below.
1598 |
1599 | ```bash
1600 | ##### add your solution here
1601 | csplit: ‘1’: line number out of range on repetition 3
1602 |
1603 | $ head row_*
1604 | ==> row_0 <==
1605 | Cradle:::Mage Errant::The Weirkey Chronicles
1606 |
1607 | ==> row_1 <==
1608 | Mother of Learning::Eight:::::Dear Spellbook:Ascendant
1609 |
1610 | ==> row_2 <==
1611 | Mark of the Fool:Super Powereds:::Ends of Magic
1612 |
1613 | $ rm row_*
1614 | ```
1615 |
1616 | **10)** Split the `items.txt` file on lines starting with a digit character. Matching lines shouldn't be part of the output and the files should be named `group_0.txt`, `group_1.txt` and so on.
1617 |
1618 | ```bash
1619 | ##### add your solution here
1620 |
1621 | $ head group_*
1622 | ==> group_0.txt <==
1623 | apple 5
1624 | banana 10
1625 |
1626 | ==> group_1.txt <==
1627 | green
1628 | sky blue
1629 |
1630 | ==> group_2.txt <==
1631 | dragon 3
1632 | unicorn 42
1633 |
1634 | $ rm group_*
1635 | ```
1636 |
1637 |
1638 |
1639 | # expand and unexpand
1640 |
1641 | **1)** The `items.txt` file has space separated words. Convert the spaces to be aligned at 10 column widths as shown below.
1642 |
1643 | ```bash
1644 | $ cat items.txt
1645 | 1) fruits
1646 | apple 5
1647 | banana 10
1648 | 2) colors
1649 | green
1650 | sky blue
1651 | 3) magical beasts
1652 | dragon 3
1653 | unicorn 42
1654 |
1655 | ##### add your solution here
1656 | 1) fruits
1657 | apple 5
1658 | banana 10
1659 | 2) colors
1660 | green
1661 | sky blue
1662 | 3) magical beasts
1663 | dragon 3
1664 | unicorn 42
1665 | ```
1666 |
1667 | **2)** What does the `expand -i` option do?
1668 |
1669 | **3)** Expand the first tab character to stop at the 10th column and the second one at the 16th column. Rest of the tabs should be converted to a single space character.
1670 |
1671 | ```bash
1672 | $ printf 'app\tfix\tjoy\tmap\ttap\n' | ##### add your solution here
1673 | app fix joy map tap
1674 |
1675 | $ printf 'appleseed\tfig\tjoy\n' | ##### add your solution here
1676 | appleseed fig joy
1677 |
1678 | $ printf 'a\tb\tc\td\te\n' | ##### add your solution here
1679 | a b c d e
1680 | ```
1681 |
1682 | **4)** Will the following code give back the original input? If not, is there an option that can help?
1683 |
1684 | ```bash
1685 | $ printf 'a\tb\tc\n' | expand | unexpand
1686 | ```
1687 |
1688 | **5)** How do the `+` and `/` prefix modifiers affect the `-t` option?
1689 |
1690 |
1691 |
1692 | # basename and dirname
1693 |
1694 | **1)** Is the following command valid? If so, what would be the output?
1695 |
1696 | ```bash
1697 | $ basename -s.txt ~///test.txt///
1698 | ```
1699 |
1700 | **2)** Given the file path in the shell variable `p`, how'd you obtain the outputs shown below?
1701 |
1702 | ```bash
1703 | $ p='~/projects/square_tictactoe/python/game.py'
1704 | ##### add your solution here
1705 | ~/projects/square_tictactoe
1706 |
1707 | $ p='/backups/jan_2021.tar.gz'
1708 | ##### add your solution here
1709 | /
1710 | ```
1711 |
1712 | **3)** What would be the output of the `basename` command if the input has no leading directory component or only has the `/` character?
1713 |
1714 | **4)** For the paths stored in the shell variable `p`, how'd you obtain the outputs shown below?
1715 |
1716 | ```bash
1717 | $ p='/a/b/ip.txt /c/d/e/f/op.txt'
1718 |
1719 | # expected output 1
1720 | ##### add your solution here
1721 | ip
1722 | op
1723 |
1724 | # expected output 2
1725 | ##### add your solution here
1726 | /a/b
1727 | /c/d/e/f
1728 | ```
1729 |
1730 | **5)** Given the file path in the shell variable `p`, how'd you obtain the outputs shown below?
1731 |
1732 | ```bash
1733 | $ p='~/projects/python/square_tictactoe/game.py'
1734 | ##### add your solution here
1735 | square_tictactoe
1736 |
1737 | $ p='/backups/aug_2024/ip.tar.gz'
1738 | ##### add your solution here
1739 | aug_2024
1740 | ```
1741 |
1742 |
--------------------------------------------------------------------------------
/exercises/all_sections.txt:
--------------------------------------------------------------------------------
1 | \:\:\:
2 | Header
3 | teal
4 | \:\:
5 | Hi there
6 | How are you
7 | \:\:
8 | banana
9 | papaya
10 | mango
11 | \:
12 | Footer
13 |
--------------------------------------------------------------------------------
/exercises/blocks.txt:
--------------------------------------------------------------------------------
1 | ----
2 | apple--banana
3 | mango---fig
4 | ----
5 | 3.14
6 | -42
7 | 1000
8 | ----
9 | sky blue
10 | dark green
11 | ----
12 | hi hello
13 |
--------------------------------------------------------------------------------
/exercises/books.txt:
--------------------------------------------------------------------------------
1 | Cradle:::Mage Errant::The Weirkey Chronicles
2 | Mother of Learning::Eight:::::Dear Spellbook:Ascendant
3 | Mark of the Fool:Super Powereds:::Ends of Magic
4 |
--------------------------------------------------------------------------------
/exercises/colors.txt:
--------------------------------------------------------------------------------
1 | deep blue
2 | light orange
3 | blue delight
4 |
--------------------------------------------------------------------------------
/exercises/duplicates.csv:
--------------------------------------------------------------------------------
1 | brown,toy,bread,42
2 | dark red,ruby,rose,111
3 | blue,ruby,water,333
4 | dark red,sky,rose,555
5 | yellow,toy,flower,333
6 | white,sky,bread,111
7 | light red,purse,rose,333
8 |
--------------------------------------------------------------------------------
/exercises/f1.txt:
--------------------------------------------------------------------------------
1 | 3) cherry
2 | 1) apple
3 | 2) banana
4 | 1) almond
5 | 4) mango
6 | 2) berry
7 | 3) chocolate
8 | 1) apple
9 | 5) cherry
10 |
--------------------------------------------------------------------------------
/exercises/fruits.txt:
--------------------------------------------------------------------------------
1 | banana
2 | papaya
3 | mango
4 |
--------------------------------------------------------------------------------
/exercises/greeting.txt:
--------------------------------------------------------------------------------
1 | Hi there
2 | Have a nice day
3 |
--------------------------------------------------------------------------------
/exercises/ip.txt:
--------------------------------------------------------------------------------
1 | it is a warm and cozy day
2 | listen to what I say
3 | go play in the park
4 | come back before the sky turns dark
5 |
6 | There are so many delights to cherish
7 | Apple, Banana and Cherry
8 | Bread, Butter and Jelly
9 | Try them all before you perish
10 |
--------------------------------------------------------------------------------
/exercises/items.txt:
--------------------------------------------------------------------------------
1 | 1) fruits
2 | apple 5
3 | banana 10
4 | 2) colors
5 | green
6 | sky blue
7 | 3) magical beasts
8 | dragon 3
9 | unicorn 42
10 |
--------------------------------------------------------------------------------
/exercises/j1.txt:
--------------------------------------------------------------------------------
1 | apple 2
2 | fig 5
3 | lemon 10
4 | tomato 22
5 |
--------------------------------------------------------------------------------
/exercises/j2.txt:
--------------------------------------------------------------------------------
1 | almond 33
2 | fig 115
3 | mango 20
4 | pista 42
5 |
--------------------------------------------------------------------------------
/exercises/j3.txt:
--------------------------------------------------------------------------------
1 | almond
2 | apple pie
3 | cold coffee
4 | honey
5 | mango shake
6 | pasta
7 | sugar
8 | tea
9 |
--------------------------------------------------------------------------------
/exercises/j4.txt:
--------------------------------------------------------------------------------
1 | apple
2 | banana shake
3 | coffee
4 | fig
5 | honey
6 | mango shake
7 | milk
8 | tea
9 | yeast
10 |
--------------------------------------------------------------------------------
/exercises/marks_1.csv:
--------------------------------------------------------------------------------
1 | Name,Biology,Programming
2 | Er,92,77
3 | Ith,100,100
4 | Lin,92,100
5 | Sil,86,98
6 |
--------------------------------------------------------------------------------
/exercises/marks_2.csv:
--------------------------------------------------------------------------------
1 | Name,Maths,Physics,Chemistry
2 | Cy,97,98,95
3 | Ith,100,100,100
4 | Lin,78,83,80
5 |
--------------------------------------------------------------------------------
/exercises/s1.txt:
--------------------------------------------------------------------------------
1 | apple
2 | coffee
3 | fig
4 | honey
5 | mango
6 | pasta
7 | sugar
8 | tea
9 |
--------------------------------------------------------------------------------
/exercises/s2.txt:
--------------------------------------------------------------------------------
1 | banana
2 | coffee
3 | eclair
4 | fig
5 | honey
6 | milk
7 | tea
8 | yeast
9 |
--------------------------------------------------------------------------------
/exercises/s3.txt:
--------------------------------------------------------------------------------
1 | apple
2 | apple
3 | guava
4 | honey
5 | tea
6 | tea
7 | tea
8 |
--------------------------------------------------------------------------------
/exercises/scores.csv:
--------------------------------------------------------------------------------
1 | Name,Maths,Physics,Chemistry
2 | Ith,100,100,100
3 | Cy,97,98,95
4 | Lin,78,83,80
5 |
--------------------------------------------------------------------------------
/images/cli_coreutils_ls.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/learnbyexample/cli_text_processing_coreutils/07bdf19ada825a0e06d3a93937f3bf740482b063/images/cli_coreutils_ls.png
--------------------------------------------------------------------------------
/images/info.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/warning.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/sample_chapters/cli_text_processing_coreutils_sample.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/learnbyexample/cli_text_processing_coreutils/07bdf19ada825a0e06d3a93937f3bf740482b063/sample_chapters/cli_text_processing_coreutils_sample.pdf
--------------------------------------------------------------------------------