≡ Menu

Understanding Linux / UNIX tr command

Q. Can you explain the tr command and how to use it under Linux / UNIX like oses?

A. The tr utility copies the given input to produced the output with substitution or deletion of selected characters. tr abbreviated as translate or transliterate. It takes as parameters two sets of characters, and replaces occurrences of the characters in the first set with the corresponding elements from the other set i.e. it is used to translate characters.

It is commonly used in shell scripts and other application.

tr command syntax

tr [options] "set1" "set2"
echo something | tr "set1" "set2"
tr "set1" "set2" < input.txt tr "set1" "set2" < input.txt > output.txt

How do I use tr command under Linux / UNIX?

Translate the word 'linux' to upper-case:
$ echo 'linux' | tr "[:lower:]" "[:upper:]"
$ echo 'linux' | tr "a-z" "A-Z"
$ echo 'I LovE linuX. one is better Than 2' | tr "a-z" "A-Z"



Create a list of the words in /path/to/file, one per line, enter:
$ tr -cs "[:alpha:]" "\n" < /path/to/file

  • -c : Complement the set of characters in string1
  • -s : Replace each input sequence of a repeated character that is listed in SET1 with a single occurrence of that character

Shell scripting example

In the following example you will get confirmation before deleting the file. If the user responds in lower case, the tr command will do nothing, but if the user responds in upper case, the character will be changed to lower case. This will ensure that even if user responds with YES, YeS, YEs etc; script should remove file:

echo -n "Enter file name : "
read myfile
echo -n "Are you sure ( yes or no ) ? "
read confirmation
confirmation="$(echo ${confirmation} | tr 'A-Z' 'a-z')"
if [ "$confirmation" == "yes" ]; then
   [ -f $myfile ] &&  /bin/rm $myfile || echo "Error - file $myfile not found"
   : # do nothing

Remove all non-printable characters from myfile.txt
$ tr -cd "[:print:]" < myfile.txt

Remove all two more successive blank spaces from a copy of the text in a file called input.txt and save output to a new file called output.txt
tr -s ' ' ' ' < input.txt > output.txt

The -d option is used to delete every instance of the string (i.e., sequence of characters) specified in set1. For example, the following would remove every instance of the word nameserver from a copy of the text in a file called /etc/resolv.conf and write the output to a file called ns.ipaddress.txt:
tr -d 'nameserver' < /etc/resolv.conf > ns.ipaddress.txt

Recommended readings:

To check the other options that can be used in the tr command, see the tr command man page, enter:
$ man tr

Tweet itFacebook itGoogle+ itPDF itFound an error/typo on this page?

{ 30 comments… add one }

  • Planet Lowyat December 23, 2007, 3:48 pm

    Great tips. Typo error -> prodcued

  • Marko February 13, 2008, 3:08 pm

    tr -d ‘nameserver’ ns.ipaddress.txt

    I think this would delete the word nameserver, but also all occurrences of characters from set {nameserver}, which could probably create big mess.

    Proper command should be:
    sed ‘s/nameserver//g’ ns.ipaddress.txt

    • Sergei September 14, 2014, 1:18 pm

      Right on.

  • Maher August 23, 2008, 11:10 am

    can you give scripts for these :
    Exercise 1: Write a shell script (named checkfiles.sh) that lists
    all text files “*.TXT” in a directory and writes the first line of each text-file to a file called Text_Heads.

    Exercise 2: Write a shell script (called words-no.sh) that counts the number of distinct words in a text file given as Argument.

    Remark: White space characters are spaces, tabs, form feeds, and new lines. Use the tr, sort, grep. wc.

    Exercise 3: Write a shell script (called cleancore.sh) that removes unwanted files from a directory and its subdirectories.
    Argument 1 is the directory where to start the search. It defaults to your home directory (If there is no directory by this name).
    Argument 2 after the directory is standard file-name that match the files that are to be removed, it defaults is ‘core’.

    • Sara April 30, 2012, 2:26 am

      No. Do your homework by yourself.

  • heba September 1, 2008, 11:45 am

    How can I get the Exercises solve??

    Please help me

  • laoa September 10, 2008, 11:02 am

    Is there any way to do the following questions

    1. Replace many different chars with one same char

    ab(cde)fg -> ab~cde~fg
    echo ab(cde)fg | tr “()” “~~”

    echo a1234b | tr “[0-9]” “A”
    a1234b ### hope aAAAAb
    echo a1234b | tr “[0-9]” “AAAA”
    echo a1234b | tr “[0-9]” “AAAAA”

    2. replace one char with two chars

    a~b -> a==b


  • nixCraft September 10, 2008, 12:21 pm


    Avoid shell escape, enter:
    echo 'ab(cde)fg' | tr "()" "~~"
    echo ab\(cde\fg | tr "()" "~~"

  • pham van hai November 11, 2008, 3:39 pm

    please help me
    convert file in window into file in linux
    I try
    cat file_linux | tr -s “\n” “\n\r” ?
    but it cannot run

  • budoliv February 6, 2009, 10:36 pm

    How do you get only the first letter capitalized?

  • Chris de Vidal March 6, 2009, 10:26 pm

    pham van hai: Use the unix2dos program instead.
    budoliv: I’d suggest you use sed instead but I don’t know the syntax off-hand.

  • Avedo May 18, 2009, 5:43 am


    Nice Tutorial. I tried to write a small shell script to rename my mp3-files, but it doesn’t work. What is wrong with it? Can someone help me?

    Greets, Andy

    for i in "*.[mM][pP]3";
            # convert uppercase to lowercase
            $n="$(echo ${i} | tr [:upper:] [:lower:])"
            # replace whitespaces with underscores
            $n="$(echo ${n} | tr [:blank:] '_')"
            # replace dots with underscores
            $n="$(echo ${n} | tr '.' '_')"
            # replace hypens with underscores
            $n="$(echo ${n} | tr '-' '_')"
            # replace multiple underscores
            $n="$(echo ${n} | tr -s '_')"
            # remove numbers at the beginning
            $n="$(echo ${n} | sed 's/^[0-9]*//')"
            # remove underscores at the beginning
            $n="$(echo ${n} | sed 's/^\_//')"
            # correct file ending
            $n="$(echo ${n} | sed 's/\_mp3/\.mp3/')"
            # rename file
            mv -v "$i" "$n";
  • nixCraft May 18, 2009, 10:18 am

    Have you tried rename command to rename multiple files? It also support regex.. Try find command to generate a file list:

    find /path/to/dir -iname "*.mp3" -print0 | while read -d $'\0' file; do your-script.sh "$file"; done

    Create your-script.sh to rename each file:

            # convert uppercase to lowercase
            $n="$(echo ${i} | tr [:upper:] [:lower:])"
            # replace whitespaces with underscores
            $n="$(echo ${n} | tr [:blank:] '_')"
            # replace dots with underscores
            $n="$(echo ${n} | tr '.' '_')"
            # replace hypens with underscores
            $n="$(echo ${n} | tr '-' '_')"
            # replace multiple underscores
            $n="$(echo ${n} | tr -s '_')"
            # remove numbers at the beginning
            $n="$(echo ${n} | sed 's/^[0-9]*//')"
            # remove underscores at the beginning
            $n="$(echo ${n} | sed 's/^\_//')"
            # correct file ending
            $n="$(echo ${n} | sed 's/\_mp3/\.mp3/')"
            # rename file
            mv -v "$i" "$n";


  • kiran June 30, 2009, 10:11 am

    try this it will work

    for i in *.
    # convert uppercase to lowercase
    n=”$(echo ${i} | tr [:lower:] [:upper:])”

    # replace whitespaces with underscores
    n=”$(echo “${n}” | tr [:blank:] ‘_’)”

    # replace dots with underscores
    n=”$(echo “${n}” | tr ‘.’ ‘_’)”

    # replace hypens with underscores
    n=”$(echo “${n}” | tr ‘-‘ ‘_’)”

    # replace multiple underscores
    n=”$(echo “${n}” | tr -s ‘_’)”

    # remove numbers at the beginning
    n=”$(echo “${n}” | sed ‘s/^[0-9]*//’)”

    # remove underscores at the beginning
    n=”$(echo “${n}” | sed ‘s/^\_//’)”

    # correct file ending
    n=”$(echo “${n}” | sed ‘s/\_mp3/\.mp3/’)”

    # rename file
    mv -v “$i” “$n”;

  • Velava June 29, 2010, 10:48 am

    To replace comma’s in .csv file by the single space i used the below script,

    tr ‘,’ ‘ ‘ output.csv

    After the above script has been executed, its giving the “Unable to Read” error message when i was trying to open the converted file such “output.csv”.
    For the small file its not giving any error, but when i m trying to covert the 8mb file it gives the above error message..

    Please help me ASAP

    thanks in advance

  • velava June 29, 2010, 10:51 am

    The script used for the above is,

    tr ‘,’ ‘ ‘ output.csv

    In the previous comment i did mistake while typing .

  • d1t1 March 21, 2011, 6:46 pm

    i have a html file with only a line and i want the output to be only the NAME and the NUMBERS

    change output like:
    NAME 542103541
    Can someone tell me how,! thx in advance!

  • d1t1 March 21, 2011, 6:48 pm

    i once tried this but it also isnt too useful:
    cat s | tr -cs “[:digit:]” “\n” > s.new0

  • pat-r September 13, 2011, 7:56 pm

    I have the following examples:
    Input Output
    AJ22 0022
    aK12 0012
    0082 0082

    Can somebody post a tr command to accomplish this.

    • Billy Baroo November 16, 2011, 3:19 pm

      Use asterisk in set2 to let set2 & set1 have equal length, e.g.

      echo “AJ22 aK12 0082″|tr ‘[:alpha:]’ ‘[0*]’

    • Lynx February 27, 2014, 12:25 am

      tr [:alpha:] 0 < filename.txt

  • rajiv November 4, 2011, 6:30 pm

    tr [A-Z][a-z] 0

  • pritam September 12, 2012, 11:14 am

    [root@localhost ~]# df -h
    Filesystem Size Used Avail Use% Mounted on
    /dev/sda8 40G 4.5G 34G 12% /
    tmpfs 2.0G 100K 2.0G 1% /dev/shm
    /dev/sda7 485M 39M 421M 9% /boot
    /dev/sda9 23G 3.3G 19G 16% /usr
    /dev/sda10 23G 323M 22G 2% /var
    /dev/mapper/vg1-lv1 3.9M 24K 3.7M 1% /root/pri
    /dev/mapper/vg1-lv2 3.9M 24K 3.7M 1% /root/prit
    3.9M 24K 3.7M 1% /root/prita

    i used awk but still not working…i want to separate “mounted on” column…
    but i fell.. here is output what i did…!!! but one more mounted directory nt seen why…????

    [root@localhost ~]# df -h | awk -F ” ” ‘{print $6}’

  • Charlie March 24, 2013, 8:11 pm


    Can somebody help me to transform this kind of expressions, like 01:22:12:345 into 01:22:12,345, please.
    I wrote this expression : tr -s ‘:[0-9][0-9][0-9]’ ‘,[0-9][0-9][0-9]’ but i had all the colons replace by commas. If I erase the -s command, the result is the same.

    If somebody can give me an help, thanks.

  • vishal March 1, 2014, 4:40 am

    Write shell script that do equivalent to tr ‘is’ ‘are’ utility.

  • Sergei September 14, 2014, 1:21 pm

    It’s a great article until:

    tr -d ‘nameserver’ ns.ipaddress.txt

    is given as an example of how to remove nameserver from /etc/resolv.conf. This should be removed from the article lest somebody does it in production somewhere.

  • bob September 30, 2014, 3:09 pm

    Input Output
    a?$ ?tg
    Translation a?$ / ?tg / ttg
    How can I convert back with a second command in script? without using opposing script or aligning both translations.
    If in/out abcd/dcba translation works either way.
    I could switch in/out with a second script.
    Looking for something like
    tr a?$ ?tg
    maybe && or : with $input or echo tr ?tg a?$ in the same script.

    • bob September 30, 2014, 7:16 pm

      Ex: input1output1 “print” output1output2 “print”
      I’m calling my script from terminal, but unable to pickup the printed output1 with tr2.
      I’m expecting to find a double output.
      Ex:hello/12334/hello or 12334/hello/12334

  • Wanderer October 26, 2014, 1:51 pm

    Thank you :)

  • barsita ray May 12, 2015, 1:45 pm

    write a shell program to find the initial of any name and display it using tr commnd.
    example:Rabindra NAth Tagore is given as input .
    Output will be R.N.Tagore.
    I cannot solve this and on friday(15.5.15) I have lab exam on this shell.

Leave a Comment