# tr - perldoc - phpman

> **TLDR:** Translate characters: run replacements based on single characters and character sets.
>
- Replace all occurrences of a character in a file, and print the result:
  `tr < {{path/to/file}} {{find_character}} {{replace_character}}`
- Replace all occurrences of a character from another command's output:
  `echo {{text}} | tr {{find_character}} {{replace_character}}`
- Map each character of the first set to the corresponding character of the second set:
  `tr < {{path/to/file}} '{{abcd}}' '{{jkmn}}'`
- Delete all occurrences of the specified set of characters from the input:
  `tr < {{path/to/file}} {{-d|--delete}} '{{input_characters}}'`
- Compress a series of identical characters to a single character:
  `tr < {{path/to/file}} {{-s|--squeeze-repeats}} '{{input_characters}}'`
- Translate the contents of a file to upper-case:
  `tr < {{path/to/file}} "[:lower:]" "[:upper:]"`
- Strip out non-printable characters from a file:
  `tr < {{path/to/file}} {{-cd|--complement --delete}} "[:print:]"`

*Source: tldr-pages*

---

    "tr/*SEARCHLIST*/*REPLACEMENTLIST*/cdsr"
            Transliterates all occurrences of the characters found (or not
            found if the "/c" modifier is specified) in the search list with
            the positionally corresponding character in the replacement
            list, possibly deleting some, depending on the modifiers
            specified. It returns the number of characters replaced or
            deleted. If no string is specified via the "=~" or "!~"
            operator, the $_ string is transliterated.

            For sed devotees, "y" is provided as a synonym for "tr".

            If the "/r" (non-destructive) option is present, a new copy of
            the string is made and its characters transliterated, and this
            copy is returned no matter whether it was modified or not: the
            original string is always left unchanged. The new copy is always
            a plain string, even if the input string is an object or a tied
            variable.

            Unless the "/r" option is used, the string specified with "=~"
            must be a scalar variable, an array element, a hash element, or
            an assignment to one of those; in other words, an lvalue.

            The characters delimitting *SEARCHLIST* and *REPLACEMENTLIST*
            can be any printable character, not just forward slashes. If
            they are single quotes ("tr'*SEARCHLIST*'*REPLACEMENTLIST*'"),
            the only interpolation is removal of "\" from pairs of "\\".

            Otherwise, a character range may be specified with a hyphen, so
            "tr/A-J/0-9/" does the same replacement as
            "tr/ACEGIBDFHJ/0246813579/".

            If the *SEARCHLIST* is delimited by bracketing quotes, the
            *REPLACEMENTLIST* must have its own pair of quotes, which may or
            may not be bracketing quotes; for example, "tr[aeiouy][yuoiea]"
            or "tr(+\-*/)/ABCD/".

            Characters may be literals, or (if the delimiters aren't single
            quotes) any of the escape sequences accepted in double-quoted
            strings. But there is never any variable interpolation, so "$"
            and "@" are always treated as literals. A hyphen at the
            beginning or end, or preceded by a backslash is also always
            considered a literal. Escape sequence details are in the table
            near the beginning of this section.

            Note that "tr" does not do regular expression character classes
            such as "\d" or "\pL". The "tr" operator is not equivalent to
            the [tr(1)](https://www.chedong.com/phpMan.php/man/tr/1/markdown) utility. "tr[a-z][A-Z]" will uppercase the 26 letters
            "a" through "z", but for case changing not confined to ASCII,
            use "lc", "uc", "lcfirst", "ucfirst" (all documented in
            perlfunc), or the substitution operator
            "s/*PATTERN*/*REPLACEMENT*/" (with "\U", "\u", "\L", and "\l"
            string-interpolation escapes in the *REPLACEMENT* portion).

            Most ranges are unportable between character sets, but certain
            ones signal Perl to do special handling to make them portable.
            There are two classes of portable ranges. The first are any
            subsets of the ranges "A-Z", "a-z", and "0-9", when expressed as
            literal characters.

              tr/h-k/H-K/

            capitalizes the letters "h", "i", "j", and "k" and nothing else,
            no matter what the platform's character set is. In contrast, all
            of

              tr/\x68-\x6B/\x48-\x4B/
              tr/h-\x6B/H-\x4B/
              tr/\x68-k/\x48-K/

            do the same capitalizations as the previous example when run on
            ASCII platforms, but something completely different on EBCDIC
            ones.

            The second class of portable ranges is invoked when one or both
            of the range's end points are expressed as "\N{...}"

             $string =~ tr/\N{U+20}-\N{U+7E}//d;

            removes from $string all the platform's characters which are
            equivalent to any of Unicode U+0020, U+0021, ... U+007D, U+007E.
            This is a portable range, and has the same effect on every
            platform it is run on. In this example, these are the ASCII
            printable characters. So after this is run, $string has only
            controls and characters which have no ASCII equivalents.

            But, even for portable ranges, it is not generally obvious what
            is included without having to look things up in the manual. A
            sound principle is to use only ranges that both begin from, and
            end at, either ASCII alphabetics of equal case ("b-e", "B-E"),
            or digits ("1-4"). Anything else is unclear (and unportable
            unless "\N{...}" is used). If in doubt, spell out the character
            sets in full.

            Options:

                c   Complement the SEARCHLIST.
                d   Delete found but unreplaced characters.
                r   Return the modified string and leave the original string
                    untouched.
                s   Squash duplicate replaced characters.

            If the "/d" modifier is specified, any characters specified by
            *SEARCHLIST* not found in *REPLACEMENTLIST* are deleted. (Note
            that this is slightly more flexible than the behavior of some tr
            programs, which delete anything they find in the *SEARCHLIST*,
            period.)

            If the "/s" modifier is specified, sequences of characters, all
            in a row, that were transliterated to the same character are
            squashed down to a single instance of that character.

             my $a = "aaabbbca";
             $a =~ tr/ab/dd/s;     # $a now is "dcd"

            If the "/d" modifier is used, the *REPLACEMENTLIST* is always
            interpreted exactly as specified. Otherwise, if the
            *REPLACEMENTLIST* is shorter than the *SEARCHLIST*, the final
            character, if any, is replicated until it is long enough. There
            won't be a final character if and only if the *REPLACEMENTLIST*
            is empty, in which case *REPLACEMENTLIST* is copied from
            *SEARCHLIST*. An empty *REPLACEMENTLIST* is useful for counting
            characters in a class, or for squashing character sequences in a
            class.

                tr/abcd//            tr/abcd/abcd/
                tr/abcd/AB/          tr/abcd/ABBB/
                tr/abcd//d           s/[abcd]//g
                tr/abcd/AB/d         (tr/ab/AB/ + s/[cd]//g)  - but run together

            If the "/c" modifier is specified, the characters to be
            transliterated are the ones NOT in *SEARCHLIST*, that is, it is
            complemented. If "/d" and/or "/s" are also specified, they apply
            to the complemented *SEARCHLIST*. Recall, that if
            *REPLACEMENTLIST* is empty (except under "/d") a copy of
            *SEARCHLIST* is used instead. That copy is made after
            complementing under "/c". *SEARCHLIST* is sorted by code point
            order after complementing, and any *REPLACEMENTLIST* is applied
            to that sorted result. This means that under "/c", the order of
            the characters specified in *SEARCHLIST* is irrelevant. This can
            lead to different results on EBCDIC systems if *REPLACEMENTLIST*
            contains more than one character, hence it is generally
            non-portable to use "/c" with such a *REPLACEMENTLIST*.

            Another way of describing the operation is this: If "/c" is
            specified, the *SEARCHLIST* is sorted by code point order, then
            complemented. If *REPLACEMENTLIST* is empty and "/d" is not
            specified, *REPLACEMENTLIST* is replaced by a copy of
            *SEARCHLIST* (as modified under "/c"), and these potentially
            modified lists are used as the basis for what follows. Any
            character in the target string that isn't in *SEARCHLIST* is
            passed through unchanged. Every other character in the target
            string is replaced by the character in *REPLACEMENTLIST* that
            positionally corresponds to its mate in *SEARCHLIST*, except
            that under "/s", the 2nd and following characters are squeezed
            out in a sequence of characters in a row that all translate to
            the same character. If *SEARCHLIST* is longer than
            *REPLACEMENTLIST*, characters in the target string that match a
            character in *SEARCHLIST* that doesn't have a correspondence in
            *REPLACEMENTLIST* are either deleted from the target string if
            "/d" is specified; or replaced by the final character in
            *REPLACEMENTLIST* if "/d" isn't specified.

            Some examples:

             $ARGV[1] =~ tr/A-Z/a-z/;   # canonicalize to lower case ASCII

             $cnt = tr/*/*/;            # count the stars in $_
             $cnt = tr/*//;             # same thing

             $cnt = $sky =~ tr/*/*/;    # count the stars in $sky
             $cnt = $sky =~ tr/*//;     # same thing

             $cnt = $sky =~ tr/*//c;    # count all the non-stars in $sky
             $cnt = $sky =~ tr/*/*/c;   # same, but transliterate each non-star
                                        # into a star, leaving the already-stars
                                        # alone.  Afterwards, everything in $sky
                                        # is a star.

             $cnt = tr/0-9//;           # count the ASCII digits in $_

             tr/a-zA-Z//s;              # bookkeeper -> bokeper
             tr/o/o/s;                  # bookkeeper -> bokkeeper
             tr/oe/oe/s;                # bookkeeper -> bokkeper
             tr/oe//s;                  # bookkeeper -> bokkeper
             tr/oe/o/s;                 # bookkeeper -> bokkopor

             ($HOST = $host) =~ tr/a-z/A-Z/;
              $HOST = $host  =~ tr/a-z/A-Z/r; # same thing

             $HOST = $host =~ tr/a-z/A-Z/r   # chained with s///r
                           =~ s/:/ -p/r;

             tr/a-zA-Z/ /cs;                 # change non-alphas to single space

             @stripped = map tr/a-zA-Z/ /csr, @original;
                                             # /r with map

             tr [\200-\377]
                [\000-\177];                 # wickedly delete 8th bit

             $foo !~ tr/A/a/    # transliterate all the A's in $foo to 'a',
                                # return 0 if any were found and changed.
                                # Otherwise return 1

            If multiple transliterations are given for a character, only the
            first one is used:

             tr/AAA/XYZ/

            will transliterate any A to X.

            Because the transliteration table is built at compile time,
            neither the *SEARCHLIST* nor the *REPLACEMENTLIST* are subjected
            to double quote interpolation. That means that if you want to
            use variables, you must use an "eval()":

             eval "tr/$oldlist/$newlist/";
             die $@ if $@;

             eval "tr/$oldlist/$newlist/, 1" or die $@;

