sebastiano.tronto.net

Source files and build scripts for my personal website
git clone https://git.tronto.net/sebastiano.tronto.net
Download | Log | Files | Refs | README

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)*