tr.md (2986B)
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. 110 111 *Next in the series: [head and tail](../2024-02-20-head-and-tail)*