diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2024-02-20 08:59:34 +0100 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2024-02-20 08:59:34 +0100 |
| commit | 4fdc98c3094efc38d57bda69dbd6dafa98e27c9c (patch) | |
| tree | 1e96bda3b5695fb998f8dc9227fa68c34693e7e0 | |
| parent | 315672cbd8eecc563b066fddea25d1440fe8fe89 (diff) | |
| download | sebastiano.tronto.net-4fdc98c3094efc38d57bda69dbd6dafa98e27c9c.tar.gz sebastiano.tronto.net-4fdc98c3094efc38d57bda69dbd6dafa98e27c9c.zip | |
Added blog post
| -rw-r--r-- | src/blog/2024-01-13-tr/tr.md | 2 | ||||
| -rw-r--r-- | src/blog/2024-02-20-head-and-tail/head-and-tail.md | 97 | ||||
| -rw-r--r-- | src/series/series.md | 1 |
3 files changed, 100 insertions, 0 deletions
diff --git a/src/blog/2024-01-13-tr/tr.md b/src/blog/2024-01-13-tr/tr.md index 207fde4..d5917b5 100644 --- a/src/blog/2024-01-13-tr/tr.md +++ b/src/blog/2024-01-13-tr/tr.md | |||
| @@ -107,3 +107,5 @@ This is pretty much all there is tu say about `tr`. All of this can | |||
| 107 | probably be done with a sufficiently complicated `sed` or `awk` | 107 | probably be done with a sufficiently complicated `sed` or `awk` |
| 108 | script, but it is definitely nice to have a simpler utility to perform | 108 | script, but it is definitely nice to have a simpler utility to perform |
| 109 | easy changes. | 109 | easy changes. |
| 110 | |||
| 111 | *Next in the series: [head and tail](../2024-02-20-head-and-tail)* | ||
diff --git a/src/blog/2024-02-20-head-and-tail/head-and-tail.md b/src/blog/2024-02-20-head-and-tail/head-and-tail.md new file mode 100644 index 0000000..bce2fbe --- /dev/null +++ b/src/blog/2024-02-20-head-and-tail/head-and-tail.md | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | # Unix text filters part 2.2 of 3: head and tail | ||
| 2 | |||
| 3 | *This post is part of a [series](../../series)* | ||
| 4 | |||
| 5 | Continuing on our series of small text-filtering utilities, we have | ||
| 6 | `head` and `tail`. They are very simple, but also very useful. | ||
| 7 | |||
| 8 | ## head | ||
| 9 | |||
| 10 | The `head` command is used to display the first few lines of a text file. | ||
| 11 | For example, the command: | ||
| 12 | |||
| 13 | ``` | ||
| 14 | $ head -n 4 [file] | ||
| 15 | ``` | ||
| 16 | |||
| 17 | Prints the first 4 lines of `[file]`. If `[file]` is not specified, | ||
| 18 | `head` reads from standard input. If the option `-n 4` is not specified, | ||
| 19 | the first 10 lines are shown. | ||
| 20 | |||
| 21 | One can also use the following alternative notation: | ||
| 22 | |||
| 23 | ``` | ||
| 24 | $ head -4 [file] | ||
| 25 | ``` | ||
| 26 | |||
| 27 | Of course, there is also the equivalent [`sed`](../2023-12-03-sed) command: | ||
| 28 | |||
| 29 | ``` | ||
| 30 | $ sed 5q [file] | ||
| 31 | ``` | ||
| 32 | |||
| 33 | ## tail | ||
| 34 | |||
| 35 | The `tail` command shows the *last* few lines of a specified file, | ||
| 36 | or of standard input. It supports the same `-n [number]` (or | ||
| 37 | `-[number]`) option where `n` defaults to 10. | ||
| 38 | |||
| 39 | However, for some reason, even in its standard POSIX variant, `tail` | ||
| 40 | has some extra features. First of all, one can add a `+` before | ||
| 41 | `[number]` to show all lines *from the `[number]`-th onwards*, | ||
| 42 | instead of the last `[number]`. For example: | ||
| 43 | |||
| 44 | ``` | ||
| 45 | $ printf '1\n2\n3\n4\n5\n' | tail -n +2 | ||
| 46 | 2 | ||
| 47 | 3 | ||
| 48 | 4 | ||
| 49 | 5 | ||
| 50 | ``` | ||
| 51 | |||
| 52 | As you can see, the line numbering is 1-based. | ||
| 53 | |||
| 54 | It is also possible to start at a specific *byte* in the text stream | ||
| 55 | using the `-c` option: | ||
| 56 | |||
| 57 | ``` | ||
| 58 | $ echo 'Hello' | tail -c 3 | ||
| 59 | lo | ||
| 60 | ``` | ||
| 61 | |||
| 62 | Notice that the ending `\n` is also included in the count. The `-c` option | ||
| 63 | also supports the `+[number]` notation: | ||
| 64 | |||
| 65 | ``` | ||
| 66 | $ echo 'Hello' | tail -c +2 | ||
| 67 | ello | ||
| 68 | ``` | ||
| 69 | |||
| 70 | There is also an `-r` option that reverses the order of the output: | ||
| 71 | |||
| 72 | ``` | ||
| 73 | $ printf '1\n2\n3\n4\n5\n' | tail -r -n 2 | ||
| 74 | 5 | ||
| 75 | 4 | ||
| 76 | ``` | ||
| 77 | |||
| 78 | Perhaps the most interesting feature of `tail` is the `-f` option, | ||
| 79 | which makes it stay open when the end of the file is reached, | ||
| 80 | displaying in real time any lines that are sunbsequently added. It | ||
| 81 | can be used like this: | ||
| 82 | |||
| 83 | ``` | ||
| 84 | $ tail -f my-log-file.log | ||
| 85 | ``` | ||
| 86 | |||
| 87 | This can be useful when the command writing to `my-log-file.log` | ||
| 88 | is already running and it is not possible to redirect its output. | ||
| 89 | |||
| 90 | The `-f` option does not work when `tail` is reading from standard | ||
| 91 | input, so technically speaking we are not in "text filter" territory | ||
| 92 | anymore, but it was mentioning. | ||
| 93 | |||
| 94 | ## Conclusions | ||
| 95 | |||
| 96 | These two utilities don't do much, but can accomplish a lot when combined | ||
| 97 | with I/O redirection and other text filters. | ||
diff --git a/src/series/series.md b/src/series/series.md index 216c105..13bd341 100644 --- a/src/series/series.md +++ b/src/series/series.md | |||
| @@ -30,6 +30,7 @@ of complexity: `grep`, `sed` and `awk`. Work in progress. | |||
| 30 | * Part 1: [grep](../blog/2023-08-20-grep) | 30 | * Part 1: [grep](../blog/2023-08-20-grep) |
| 31 | * Part 2: [sed](../blog/2023-12-03-sed) | 31 | * Part 2: [sed](../blog/2023-12-03-sed) |
| 32 | * Part 2.1: [tr](../blog/2024-01-13-tr) | 32 | * Part 2.1: [tr](../blog/2024-01-13-tr) |
| 33 | * Part 2.2: [head and tail](../blog/2024-02-20-head-and-tail) | ||
| 33 | * Part 3: awk (coming "soon") | 34 | * Part 3: awk (coming "soon") |
| 34 | 35 | ||
| 35 | ## The UNIX shell as an IDE | 36 | ## The UNIX shell as an IDE |
