echo 'abcd' | tr '[a-z]' '[A-Z]'
isn't the single qotation supposed to protect the [] ??
how does it work !!
i get ABCD
i just want to know how does it work
quotation must protect the [a-z]
so it must seach for [a-z] and change it to [A-Z]
finally when he finds the letter from a to z how does he know he must change it with the upper case
we told him to change it with any letter from A to Z
what do you get?
what are you expecting to get?
i get ABCD
i just want to know how does it work
quotation must protect the [a-z]
so it must seach for [a-z] and change it to [A-Z]
finally when he finds the letter from a to z how does he know he must change it with the upper case
we told him to change it with any letter from A to Z
@noor2001 , I'd suggest rereading man tr - it should explain the basics.
As an example:
$echo 'abcde' | tr '[a-e]' '[1-5]'
12345
$echo 'ebacd' | tr '[a-e]' '[1-5]'
52134
Do come back if there's still something unclear.
thank you very much seems more logical know
but what are the qutations ' ' for
The single quotations are to protect the character sets in case they include shell special characters, like * or interpreted sequences like \r. Quotes are not always needed, but using them avoids errors.
What you missed in the man page is the very first example:
CHAR1-CHAR2 means "all characters from CHAR1 to CHAR2 in ascending order"
There are no square brackets when you specify a range. It is always 3 characters, and the middle one is a -. For example, the example below echoes 8 consecutive characters in the ASCII table. The first arg to tr means "between ) and - inclusive". The second arg needs only one char -- see the note in the man page that "SET2 is extended to length of SET1 by repeating its last character as necessary".
$ echo '()*+,-./'
()*+,-./
$ echo '()*+,-./' | tr ')--' 'x'
(xxxxx./
All the arg types enclosed in square brackets are either character classes, or operators that control repeats in the second arg.
tr is rather old-school. Its args are unconventional, as they represent corresponding character sets, not patterns. Also, I believe it works on bytes, and takes little notice of locale or UTF.
thank you very much bro
you are saying
single quotations are to protect the character sets in case they include shell special characters, like * or interpreted sequences like \r
so why didn't they protect the square brackets here
echo 'abcd' | tr '[a-z]' '[A-Z]'
what i mean is $ echo '()*+,-./' | tr ')--' 'x'
')--' must be protected by the single quotations
and taken as it is
is - range not a special characters
It did protect the square brackets. These are not patterns, they are merely list of characters. The square brackets have no special significance in tr, and only one input character is considered at a time.
If the square brackets were not protected, they would cause shell filename expansion to be attempted.
The two range args expand into long character sequences. Then, any occurrence of a character in SET1 is replaced by the character in the same position in SET2.
SET1 is [abcdefghijklmnopqrstuvwxyz]
SET2 is [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
Alter: ^^^^
Or again:
$ echo '[abcdefg' | tr '[a-z' '@ZbRdK'
@ZbRdKKK
This does reveal an error in my previous post : you can have multiple ranges, together with single characters, in a single arg. If you want - as a literal character, you have to put it first or last (thus it cannot be part of a range). If it is first, it looks like an option, so you need to use the -- option to have the first arg treated as such.
$ echo 'Range like a-j or r-t' | tr '-i-l' '%I-L'
tr: invalid option -- 'i'
Try 'tr --help' for more information.
$ echo 'Range like a-j or r-t' | tr -- '-i-l' '%I-L'
Range LIKe a%J or r%t
You possibly need to experiment with more complex tests of tr to understand it in full. ABCD is not much of a test case.
Thank you again
But I still return to zero
Why is the range not protected in the middle
While we are using quotations
sorry to chime in so late, but
Not sure what the question means. What "protection" are you referring to?
single quote prevent the shell from "expanding/glob-ing" the string that's being quoted.
echo 'Range like a-j or r-t' | tr -- '-i-l' '%I-L'
could have been written as producing the same results.
echo 'Range like a-j or r-t' | tr -- -i-l %I-L
Using single-quotes or double-quotes (if intended) is the best practice that could (in the long run) save you some major headaches.
As for the tr specifics (in additions to what the others have elaborated on, I'd suggest rereading man tr or GNU tr.
Not sure if my comments have made anything clearER though....
P.S. to read up on shell quoting refer to this GNU quoting.
Thank you
I mean shouldn’t it compare
'-i-l' As it is not as a range because we are using quotation
echo 'Range like a-j or r-t' | tr -- '-i-l' '%I-L'
It is a "range" for tr - regardless whether you're using quotes (of any kind) or not.
Quotes simply pass the quoted string "as-is" to the utility (tr in your case) without the shell expanding potential shell special meta/wild-card characters (e.g. *,$ ,{ etc).
I think you're not clear of the purpose of the quotations. I'd suggest rereading the the link from the previous post for GNU quoting.
The quotes are for the shell, to not do substitutions on it. It will hand the arguments unquoted to the tr
For example
$ echo 'x' "x" \x x
x x x x
The quotings are removed then handed to the echo.
But
$ echo '*' "*" \* *
* * * some matching files here
The shell expands the unprotected * then hands the result to the echo.
Another exercise:
$ touch a b c
$ echo '[a-z]' [a-z]
[a-z] a b c
Again, the shell expands the unprotected [a-z] with the matching file names.
As was mentioned in the previous posts, tr handles character sets by default. There is no need for wrapping a range in [ ]
tr 'a-z' 'A-Z'
tr '[:lower:]' '[:upper:]'
The latter is a character class that needs a further [ ]
Compare with a Regular Expression, here in sed:
sed 's/[a-z]/X/g'
sed 's/[[:lower:]]/X/g'
The Regular Expression needs a character set in [ ].
What does tr '[a-z]' '[A-Z]' do?
The tr sees [a-z] [A-Z] and maps
[ --> [ (character)
a-z --> A-Z (range)
] --> ] (character)
So the extra [ ] do not harm - but can mislead the human.
thank you
this is literally what I was looking for
my doctor said something else
do you advise me to study from the book or to look for a good course and do you have any course suggestion
Actually I've got my knowledge from the man pages (Unix and Linux) and from further systematic experimenting.
In Linux you have even
man 1p tr
1p is the POSIX standard, and how a Unix tr should work.
(And a Linux tr tries to be compatible with it.)