diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2024-01-15 12:01:24 +0100 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2024-01-15 12:01:24 +0100 |
| commit | 7dac2c3bc3ea70ed52b25a08566b760af41e6f1a (patch) | |
| tree | f7bfcfd65ded542cf4041af16aee1ccb7d570556 /src/blog | |
| parent | 57ef2d54ef65043cc3fcc18b474dad140bfe70aa (diff) | |
| parent | 5f6abc4ce6cca02a37f341f46cc302d20973dae0 (diff) | |
| download | sebastiano.tronto.net-7dac2c3bc3ea70ed52b25a08566b760af41e6f1a.tar.gz sebastiano.tronto.net-7dac2c3bc3ea70ed52b25a08566b760af41e6f1a.zip | |
Merge branch 'master' of tronto.net:sebastiano.tronto.net
Diffstat (limited to 'src/blog')
| -rw-r--r-- | src/blog/2023-12-03-sed/sed.md | 4 | ||||
| -rw-r--r-- | src/blog/2024-01-13-tr/tr.md | 109 |
2 files changed, 112 insertions, 1 deletions
diff --git a/src/blog/2023-12-03-sed/sed.md b/src/blog/2023-12-03-sed/sed.md index c422879..4d50ed9 100644 --- a/src/blog/2023-12-03-sed/sed.md +++ b/src/blog/2023-12-03-sed/sed.md | |||
| @@ -399,4 +399,6 @@ to take a small detour and talk about some other simple, special-purpose | |||
| 399 | text filtering commands, such as `tr`, `head`, `fmt` and so on. Expect | 399 | text filtering commands, such as `tr`, `head`, `fmt` and so on. Expect |
| 400 | some short posts in this series before part 3 - after all, there are | 400 | some short posts in this series before part 3 - after all, there are |
| 401 | [uncountably many](https://en.wikipedia.org/wiki/Uncountable_set) | 401 | [uncountably many](https://en.wikipedia.org/wiki/Uncountable_set) |
| 402 | numbers between two and 3! | 402 | numbers between 2 and 3! |
| 403 | |||
| 404 | *Next in the series: [tr](../2024-01-13-tr)* | ||
diff --git a/src/blog/2024-01-13-tr/tr.md b/src/blog/2024-01-13-tr/tr.md new file mode 100644 index 0000000..207fde4 --- /dev/null +++ b/src/blog/2024-01-13-tr/tr.md | |||
| @@ -0,0 +1,109 @@ | |||
| 1 | # UNIX text filters, part 2.1 of 3: tr | ||
| 2 | |||
| 3 | *This post is part of a [series](../../series)* | ||
| 4 | |||
| 5 | In the [post about sed](../2023-12-03-sed) I have not discussed the | ||
| 6 | `y` command at all. This is because I realized it is just an | ||
| 7 | underpowered version of the `tr` command, that we are going to | ||
| 8 | explore in this post. | ||
| 9 | |||
| 10 | The `tr` command is a simple utility that can perform | ||
| 11 | character-by-character substitutions and a couple of other things. | ||
| 12 | Like most UNIX utilities, it operates on standard input and standard | ||
| 13 | output by default. | ||
| 14 | |||
| 15 | ## Replacing | ||
| 16 | |||
| 17 | The most basic form of a `tr` command is | ||
| 18 | |||
| 19 | ``` | ||
| 20 | $ tr string1 string2 | ||
| 21 | ``` | ||
| 22 | |||
| 23 | which replaces every occurrence of a character present in `string1` | ||
| 24 | with its corresponding character in `string2` - the first with the | ||
| 25 | first, the second with the second and so on. If `string2` is shorter | ||
| 26 | than `string1`, the last character is repeated as needed. | ||
| 27 | |||
| 28 | For example | ||
| 29 | |||
| 30 | ``` | ||
| 31 | $ echo 'Hello!' | tr le 13 | ||
| 32 | H311o! | ||
| 33 | ``` | ||
| 34 | |||
| 35 | An equivalent `sed` command would be `sed 'y/le/13/'`. | ||
| 36 | |||
| 37 | Like sed and [grep](../2023-08-20-grep), also `tr` supports the | ||
| 38 | standard character sets like `[:upper:]`, `[:alpha:]` and so on. | ||
| 39 | For example, the following command capitalizes every letter in the | ||
| 40 | input string: | ||
| 41 | |||
| 42 | ``` | ||
| 43 | $ echo 'Hello!' | tr [:lower:] [:upper:] | ||
| 44 | HELLO! | ||
| 45 | ``` | ||
| 46 | |||
| 47 | ## Deleting | ||
| 48 | |||
| 49 | With the `-d` option one can delete characters: | ||
| 50 | |||
| 51 | ``` | ||
| 52 | $ echo 'R42emo3vin0g all n66umber3s!' | tr -d 0-9 | ||
| 53 | Removing all numbers! | ||
| 54 | ``` | ||
| 55 | |||
| 56 | Here I have used the *character range* `0-9` instead of `[:digit:]`. | ||
| 57 | Other examples of valid character ranges are `A-Z`, `0-8` and `a-f`. | ||
| 58 | |||
| 59 | The `-d` option can be combined with the `-c` option, which takes | ||
| 60 | the *complement* of a given set of characters: | ||
| 61 | |||
| 62 | ``` | ||
| 63 | $ echo 'R42emo3vin0g all non-n66umber3s!' | tr -cd '0-9\n' | ||
| 64 | 4230663 | ||
| 65 | ``` | ||
| 66 | |||
| 67 | Notice that I have also added `\n` to our list of | ||
| 68 | characters, so that the newline at the end of the text is kept. | ||
| 69 | |||
| 70 | A more complex example involving `tr -cd` is the following, which | ||
| 71 | I use to generate random passowrds: | ||
| 72 | |||
| 73 | ``` | ||
| 74 | $ cat /dev/random | tr -cd 'a-z0-9' | fold -w 12 | head -n 1 | ||
| 75 | ft82mtfsy5ps | ||
| 76 | ``` | ||
| 77 | |||
| 78 | Here `/dev/random` spits out random data, while the commands | ||
| 79 | `fold -w 12` and `head -n 1` are used to break the input text into | ||
| 80 | lines of 12 characters and take the first line of the input, | ||
| 81 | respectively. We'll talk about them in future posts. | ||
| 82 | |||
| 83 | ## Squeezing | ||
| 84 | |||
| 85 | One more thing `tr` can do is *squeezing* consecutive identical | ||
| 86 | characters. For example: | ||
| 87 | |||
| 88 | ``` | ||
| 89 | $ echo Helllllo | tr -s l | ||
| 90 | Helo | ||
| 91 | ``` | ||
| 92 | |||
| 93 | The `-s` option can be combined with the `-c` or `-d` option, and | ||
| 94 | in this case the squeezing is performed last, squeezing all the | ||
| 95 | characters contained in the last given string: | ||
| 96 | |||
| 97 | ``` | ||
| 98 | $ echo 'Hellllo! 112233' | tr -s 'l_e' '123' | ||
| 99 | H31o! 123 | ||
| 100 | $ echo 'Hello!' | tr -ds '!' 'l' | ||
| 101 | Helo | ||
| 102 | ``` | ||
| 103 | |||
| 104 | ## Conclusions | ||
| 105 | |||
| 106 | 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` | ||
| 108 | script, but it is definitely nice to have a simpler utility to perform | ||
| 109 | easy changes. | ||
