├── 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 |

CLI text processing with GNU Coreutils ebook cover image

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 | >![info](../images/info.svg) 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 | >![info](../images/info.svg) 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 | >![info](../images/info.svg) 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 | >![info](../images/info.svg) 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 | >![info](../images/info.svg) 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 | >![info](../images/info.svg) 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 | >![info](../images/info.svg) 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 --------------------------------------------------------------------------------