Line: 1 to 1 | ||||||||
---|---|---|---|---|---|---|---|---|
Pub Talk Part III
| ||||||||
Line: 700 to 700 | ||||||||
'Why don't you write a little script that informs whether an user is logged on or not?? Meanwhile: WAITER?? two more pints, please...' | ||||||||
Added: | ||||||||
> > | next -- PauloSantana - 25 Dec 2017 | |||||||
-- JulioNeves - 01 Aug 2006
|
Line: 1 to 1 | ||||||||
---|---|---|---|---|---|---|---|---|
Pub Talk Part III | ||||||||
Changed: | ||||||||
< < | ||||||||
> > | ||||||||
Added: | ||||||||
> > | This is a very new translation from Portuguese to English. Please contribute to the development of this site indicating errors and and/or suggesting corrections and materials for this person. | |||||||
'Get me two pints waiter, I've got a lot to talk!' |
Line: 1 to 1 | ||||||||
---|---|---|---|---|---|---|---|---|
Pub Talk Part III | ||||||||
Line: 699 to 699 | ||||||||
'Why don't you write a little script that informs whether an user is logged on or not?? Meanwhile: WAITER?? two more pints, please...' -- JulioNeves - 01 Aug 2006 | ||||||||
Added: | ||||||||
> > |
|
Line: 1 to 1 | ||||||||
---|---|---|---|---|---|---|---|---|
Pub Talk Part III |
Line: 1 to 1 | ||||||||
---|---|---|---|---|---|---|---|---|
Pub Talk Part III | ||||||||
Line: 71 to 71 | ||||||||
$ cat musics | ||||||||
Changed: | ||||||||
< < | album 1^Artista1~Musica1:Artista2~Musica2 album 2^Artista3~Musica3:Artista4~Musica4 album 3^Artista5~Musica5:Artista6~Musica5 album 4^Artista7~Musica7:Artista8~Musica8 | |||||||
> > | album 1^Musician1~Music1:Musician2~Music2 album 2^Musician3~Music3:Musician4~Music4 album 3^Musician5~Music5:Musician6~Music5 album 4^Musician7~Music7:Musician8~Music8 | |||||||
'So, the layout is the following one:' | ||||||||
Changed: | ||||||||
< < | nome do album^interprete1~nome da musica1:...:interpreten~nome da musican | |||||||
> > | album^Musician1~music1:...:Musician~musicn | |||||||
'That means that the name of the album is separated by a circumflex (or caret ^ ) from the rest of the register. This register is made of several groups (composed by: the singer of each song and the song). The artist and the name of the song are separated by a tilde (~ ), and a colon (: ) separates the name of the song and the name of the singer.' | ||||||||
Line: 90 to 90 | ||||||||
$ cut -f2 -d: musics | ||||||||
Changed: | ||||||||
< < | Artista2~Musica2 Artista4~Musica4 Artista6~Musica5 Artista8~Musica8 | |||||||
> > | Musician2~Music2 Musician4~Music4 Musician6~Music5 Musician8~Music8 | |||||||
'That means that we have cut the second field (-f ) delimited (-d ) with a colon (: ). But if we just wanted the names of the interpreters we should have used a different syntax:'
$ cut -f2 -d: musics | cut -f1 -d~ | ||||||||
Changed: | ||||||||
< < | Artista2 Artista4 Artista6 Artista8 | |||||||
> > | Musician2 Musician4 Musician6 Musician8 | |||||||
'In order to understand it, let's use the first line of musics:'
$ head -1 musics | ||||||||
Changed: | ||||||||
< < | album 1^Artista1~Musica1:Artista2~Musica2 | |||||||
> > | album 1^Musician1~Music1:Musician2~Music2 | |||||||
'Watch me now:'
Delimitating the first cut (: ) | ||||||||
Changed: | ||||||||
< < | album 1^Artista1~Musica1:Artista2~Musica2 | |||||||
> > | album 1^Musician1~Music1:Musician2~Music2 | |||||||
Changed: | ||||||||
< < | 'This way, at the first cut , the first delimiting field (-d ) colon (: ) is album 1^Artista1~Musica1 and the second one, that is of our interest, is Artista2~Musica2. ' | |||||||
> > | 'This way, at the first cut , the first delimiting field (-d ) colon (: ) is album 1^Musician1~Music1 and the second one, that is of our interest, is Musician2~Music2. ' | |||||||
'Let's see then, what's happened to the second cut :'
New delimitating character (~ ) | ||||||||
Changed: | ||||||||
< < | Artista2~Musica2 | |||||||
> > | Musician2~Music2 | |||||||
Changed: | ||||||||
< < | 'Now the first field of the delimitating character (-d ) tilde (~ ) is of our interest and it is Artista2 and the second field is Musica2.' | |||||||
> > | 'Now the first field of the delimitating character (-d ) tilde (~ ) is of our interest and it is Musician2 and the second field is Music2.' | |||||||
'Considering that our first assumption was applied to the rest of the file, we'll get that same answer.' | ||||||||
Line: 580 to 580 | ||||||||
fi | ||||||||
Changed: | ||||||||
< < | 'Notice that the if command tests the grep command (that's its purpose). If the if command succeeds (in the case above, that means: if the user - whose name is in $1 - is found at /etc/passwd ) the then set of commands is executed (in this example, only the echo command). Otherwise, the instructions of the else set are executed, where new if tests whether the useradd command works including the user $1 in /etc/passwd or not, in this case an error message is exhibited asking if the gay is root.' | |||||||
> > | 'Notice that the if command tests the grep command (that's its purpose). If the if command succeeds (in the case above, that means: if the user - whose name is in $1 - is found at /etc/passwd ) the then set of commands is executed (in this example, only the echo command). Otherwise, the instructions of the else set are executed, where new if tests whether the useradd command works including the user $1 in /etc/passwd or not, in this case an error message is exhibited asking if the guy is root.' | |||||||
'Let's check the command, firstly trying to execute it with a pre existent user:' | ||||||||
Line: 653 to 653 | ||||||||
'See? As I told you, as long as we talk and drink, our programming skills are improving. Let's see how we can enhance our music software:' | ||||||||
Changed: | ||||||||
< < | ****************************** ... ****************************** 'It's an evolution of the previous version, see? Instead of including a register (that could be duplicated in the previous version), we now test if the begining (^) and the end ($) of a register match to the informed parameter ($1). A '^' is used at the begining of the chain and a '$' is used at the end of it in order to test whether the parameter informed equals to some previously registered data.' | |||||||
> > |
$ cat musinc
#!/bin/bash
# Include Musics (version 3)
#
if grep "^$1$" musicas > /dev/null
then
echo This album is already registered
else
echo $1 >> musics
sort musics -o musics
fi
'It's an evolution of the previous version, see? Instead of including a register (that could be duplicated in the previous version), we now test if the begining (^ ) and the end ($ ) of a register match to the informed parameter ($1 ). A ^ is used at the begining of the string and a $ is used at the end of it in order to test whether the parameter informed equals to some previously registered data.' | |||||||
'Let's run it now, informing a previously registered album' | ||||||||
Changed: | ||||||||
< < | ****************************** ... ****************************** | |||||||
> > |
$ musinc "album 4^Musician7~Music7:Musician8~Music8"
This album is already registered
| |||||||
'And now a non registered one: ' | ||||||||
Changed: | ||||||||
< < | ****************************** ... ****************************** 'As you've seen, our software is slowly improving, and it will get even better as long as we pass through these shell classes.' | |||||||
> > | $ musinc "album 5^Musician9~Music9:Musician10~Music10" $ cat musicas album 1^Musician1~Music1:Musician2~Music2 album 2^Musician3~Music3:Musician4~Music4 album 3^Musician5~Music5:Musician6~Music5 album 4^Musician7~Music7:Musician8~Music8 album 5^Musician9~Music9:Musician10~Music10 'As you've seen, our software is slowly improving, and it will get even better as long as we pass through these shell classes.' | |||||||
'I've got all that you said, but I still don't get how I can do an if in order to test conditions, which I think that would be the main function of the command.' | ||||||||
Line: 676 to 697 | ||||||||
'Why don't you write a little script that informs whether an user is logged on or not?? Meanwhile: WAITER?? two more pints, please...' | ||||||||
Deleted: | ||||||||
< < | album 1^Artista1~Musica1:Artista2~Musica2
![]() | |||||||
-- JulioNeves - 01 Aug 2006 |
Line: 1 to 1 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
Pub Talk Part III | ||||||||||
Line: 89 to 89 | ||||||||||
'So, in order to cut the piece of information that refers to the the second songs of the file musics , we must do the following:'
| ||||||||||
Changed: | ||||||||||
< < | $ cut -f2 -d: musicas | |||||||||
> > | $ cut -f2 -d: musics | |||||||||
Artista2~Musica2 Artista4~Musica4 Artista6~Musica5 | ||||||||||
Line: 290 to 290 | ||||||||||
| ||||||||||
Changed: | ||||||||||
< < |
| |||||||||
> > |
| |||||||||
Removing characters with tr | ||||||||||
Line: 300 to 300 | ||||||||||
'I'll show you an example of such an aberration:' | ||||||||||
Changed: | ||||||||||
< < | $ cat confuso echo Read an online shell book at http://www.julioneves.com > book;cat book;pwd;ls;rm -f book 2>/dev/null;cd ~ | |||||||||
> > | $ cat confusion echo Read an online shell book at http://www.julioneves.com > book;cat book;pwd;ls;rm -f trash 2>/dev/null;cd ~ | |||||||||
'When the script was run, the answer was:' | ||||||||||
Changed: | ||||||||||
< < | $ confuso Read an online shell book at http://www.julioneves.com | |||||||||
> > | $ confusion Read an online shell book at http://www.julioneves.com | |||||||||
/home/jneves/LM | ||||||||||
Changed: | ||||||||||
< < | confuso livro musexc musics musinc muslist number | |||||||||
> > | confusion book musexc musics musinc muslist number | |||||||||
'But, since I was meant to grade the script, I had to evaluate it seriously, so, to understand what he has done, I called him and in front of him, I ran the following command:' | ||||||||||
Changed: | ||||||||||
< < | $ tr ";" "\n" < confuso echo Read an online shell book at http://www.julioneves.com | |||||||||
> > | $ tr ";" "\n" < confusion echo Read an online shell book at http://www.julioneves.com | |||||||||
pwd | ||||||||||
Added: | ||||||||||
> > | ls rm -f trash 2>/dev/null | |||||||||
cd ~ | ||||||||||
Deleted: | ||||||||||
< < | ls -l rm -f lixo 2>/dev/null | |||||||||
Changed: | ||||||||||
< < | 'I don't have to tell you how disapointed he got when I, in a few seconds, undid the joke he had spent hours doing.' | |||||||||
> > | 'I don't have to tell you how disapointed he got when I, in a few seconds, undid the joke he had spent hours doing.' | |||||||||
Changed: | ||||||||||
< < | 'But, pay attention! If I were using a Unix system, the command would be:' ****************************** ... ****************************** | |||||||||
> > | 'But, pay attention! If I were using a Unix system (with ksh ou sh ), the command should be:'
$ tr ";" "\012" < confusion
Shrinking with tr | |||||||||
Deleted: | ||||||||||
< < | Compressing with tr | |||||||||
'See the difference between two executions of the date command (one I ran today and the other I ran two weeks ago):' | ||||||||||
Changed: | ||||||||||
< < | ****************************** ... ****************************** | |||||||||
> > |
$ date # Today
Sun Sep 19 14:59:54 2004
$ date # Two weeks ago
Sun Sep 5 10:12:33 2004
| |||||||||
'If I wanted to isolate the hour, I should do the following:' | ||||||||||
Changed: | ||||||||||
< < | ****************************** ... ****************************** | |||||||||
> > |
$ date | cut -f 4 -d ' '
14:59:54
| |||||||||
'On the other hand, two weeks ago, the answer would be:' | ||||||||||
Changed: | ||||||||||
< < | ****************************** ... ****************************** | |||||||||
> > |
$ date | cut -f 4 -d ' '
5
| |||||||||
'But pay attention to the following detail:' | ||||||||||
Deleted: | ||||||||||
< < | ****************************** ... ****************************** 'As you can see, there are two blank spaces before the number # (day). That ruins it all, because the third part is empty and the fourth is the day (#). The ideal would be to compress the sucessive blank spaces into just one in order to work with the two chains. See how you can do it:' ****************************** ... ****************************** 'Now I could cut it:' ****************************** ... ****************************** 'See how shell can be handful? Now, take a look at the following file, that originally came from that operational system that is vulnerable to all sorts of virus.' ****************************** ... ****************************** 'Let-me give you two clues:' | |||||||||
Changed: | ||||||||||
< < | #1 - The option -v of the cat command shows the invisible control characters, with the notation ^L, in which ^ stands for the control key and L stands for the L key. The option -e shows the end of the line with a $. | |||||||||
> > | $ date # Two weeks ago
Sun Sep 5 10:12:33 2004
'As you can see, there are two blank spaces before the number 5 (day). That ruins it all, because the third part is empty and the fourth is the day (5 ). The ideal would be to compress the sucessive blank spaces into just one in order to work with the two strings. See how you can do it:'
$ date | tr -s " "
Sun Sep 5 10:12:33 2004
'You can see there is no more two spaces Now I can cut it:'
$ date | tr -s " " | cut -f 4 -d " "
10:12:33
'See how shell can be handful? Now, take a look at the following file, that originally came from that operational system that is vulnerable to all sorts of virus.' | |||||||||
Changed: | ||||||||||
< < | #2 - That happens because in DOS (or rwin) formated files, there is a Carriage-Return (\r) and a line-feed (\f) at the end of the registers. In Linux formated files, on the other hand, there is only a line-feed at the end of the registers. | |||||||||
> > | ![]() \r ) and a line-feed (\n ) at the end of the registers. In Linux formated files, on the other hand, there is only a line-feed at the end of the registers.
| |||||||||
'Let's clean the file now' | ||||||||||
Changed: | ||||||||||
< < | ****************************** ... ****************************** | |||||||||
> > |
$ tr -d '\r' < FileFromDOS.txt > /tmp/$$
$ mv -f /tmp/$$ FileFromDOS.txt
| |||||||||
'Check now what's happened:' | ||||||||||
Deleted: | ||||||||||
< < | ****************************** ... ****************************** 'The option -d of the tr command removes a character (the one that has been specified) from the whole file. Thus, I have removed the unwishful characters saving the text in a temporary file (that afterwards became the substitute of the original file).' ****************************** ... ****************************** | |||||||||
Changed: | ||||||||||
< < | 'PS: If I were using a Unix machine, I should do the following:' ****************************** ... ****************************** 'That has happened because ftp was run on binary mode (or image), and it means: no text interpretation. If, before the file transmission, the option ascii had been defined, that wouldn't have happened.' | |||||||||
> > |
$ cat -ve FileFromDOS.txt
This file$
was recorded by$
the Windows and$
downloaded by$
a badly done ftp.$
'The option -d of the tr command removes a character (the one that has been specified) from the whole file. Thus, I have removed the unwishful characters saving the text in a temporary file (that afterwards became the substitute of the original file).'If I were using a Unix machine (with ksh ou sh ), the command should be:
$ tr -d '\015' < FileFromDOS.txt > /tmp/$$
$ mv -f /tmp/$$ FileFromDOS.txt
![]() | |||||||||
'Well, those hints are making me enjoy this shell stuff, but there are many things I still can't do.' | ||||||||||
Changed: | ||||||||||
< < | 'Nevermind! There are still many things for you to learn about shell programming. But you are ready to solve a lot of problems using what you've learnt as long as you adopt a "shell way of thinking". Are you able to make a script that tells me who's been logged in for more than one day at your server?' | |||||||||
> > | 'Nevermind! There are still many things for you to learn about shell programming. But you are ready to solve a lot of problems using what you've learn as long as you adopt a "shell way of thinking". Are you able to make a script that tells me who's been logged in for more than one day at your server?' | |||||||||
'Surely not!! I would have to use conditional commands that I still don't know.' 'Why don't you change a little bit your way of thinking and come to the shell side of the force? Waiter, my pal, bring us some pints before we proceed... 'Now, that we have our pints, let's solve that problem. Pay attention to the who command:' | ||||||||||
Changed: | ||||||||||
< < | ****************************** ... ****************************** 'And also to the date command ' ****************************** ... ****************************** | |||||||||
> > |
$ who
jneves pts/1 Sep 18 13:40
rtorres pts/0 Sep 20 07:01
rlegaria pts/1 Sep 20 08:19
lcarlos pts/3 Sep 20 10:01
'And also to the date command '
$ date
Mon Sep 20 10:47:19 BRT 2004
| |||||||||
'Now look: month and day are presented in the same format by both commands.' | ||||||||||
Changed: | ||||||||||
< < | 'Sometimes different commands present outputs in different languages. When that happens, you can do the following:' ****************************** ... ****************************** 'This way, you can print a bit of uniformity to the languages employed.' | |||||||||
> > | ||||||||||
Changed: | ||||||||||
< < | 'Well, if there is a register of who in which we don't find today's date, that means the user has been logged in for more than one day (considering that the user can't be logged in since tomorrow)... So, let's save the piece of data that is of our interest.' ****************************** ... ****************************** 'I have used the construction $(...), in order to priorize the execution of the commands before attributing its output to the variable $Data. Let's see how it works:' ****************************** ... ****************************** 'Sweet! Now, what we should do is to look for the registers that do not present that day in the output of the who command.' | |||||||||
> > | 'Well, if there is a register of who in which we don't find today's date, that means the user has been logged in for more than one day (considering that the user can't be logged in since tomorrow)... So, let's save the piece of data that is of our interest.' | |||||||||
Changed: | ||||||||||
< < | 'I see! Well, and since you've mentioned the action of searching, I'm thinking of grep. Am I right?' | |||||||||
> > | $ Data=$(date | cut -c 5-10)
| |||||||||
Changed: | ||||||||||
< < | 'That is RIGHT! Very good! But I need to use grep with that option that makes it list just the registers in which there is not the chain. Any idea?' | |||||||||
> > | 'I have used the construction $(...) , in order to priorize the execution of the commands before attributing its output to the variable $Data . Let's see how it works:' | |||||||||
Changed: | ||||||||||
< < | 'Well, yeah... hummm... is it -v?' | |||||||||
> > | $ echo $Data
Sep 20
'Sweet! Now, what we should do, is to look for the registers that do not present that day in the output of the who command.'
'I see! Well, and since you've mentioned the action of searching, I'm thinking of grep . Am I right?'
'That is RIGHT! Very good! But I need to use grep with that option that makes it list just the registers in which there is not the string. Any idea?'
'Well, yeah... hummm... is it -v ?' | |||||||||
'In fact, it IS! You're getting good at it! So let's see:' | ||||||||||
Changed: | ||||||||||
< < | ****************************** ... ****************************** | |||||||||
> > |
$ who | grep -v "$Data"
jneves pts/1 Sep 18 13:40
| |||||||||
'And if I wanted something a little prettier, I would do the following:' | ||||||||||
Deleted: | ||||||||||
< < | ****************************** ... ****************************** | |||||||||
Changed: | ||||||||||
< < | 'See? No conditional was necessary. Specially when we consider that our conditional (if) does not test conditions, but instructions, as we shall see.' | |||||||||
> > | $ who | grep -v "$Data" | cut -f1 -d ' '
jneves
'See? No conditional was necessary. Specially when we consider that our conditional (if ) does not test conditions, but instructions, as we shall see.'
Conditional Commands | |||||||||
Deleted: | ||||||||||
< < | Conditional Commands | |||||||||
'Check the lines below:' | ||||||||||
Deleted: | ||||||||||
< < | ****************************** ... ****************************** | |||||||||
Changed: | ||||||||||
< < | 'What that $ does? It looks like a variable, is it?' | |||||||||
> > |
$ ls musics
musics
$ echo $?
0
$ ls FileThatDontExists
ls: FileThatDontExists: No such file or directory
$ echo $?
1
$ who | grep jneves
jneves pts/1 Sep 18 13:40 (10.2.4.144)
$ echo $?
0
$ who | grep juliana
$ echo $?
1
'What that $? does? It looks like a variable, is it?' | |||||||||
Changed: | ||||||||||
< < | 'Yes, it is a variable that contains the returning code of the last instruction run. I can assure you that if this instruction succeeded, "$?" equals zero, otherwise, it will be different.' | |||||||||
> > | 'Yes, it is a variable that contains the returning code of the last instruction run. I can assure you that if this instruction succeeded, $? equals zero, otherwise, it will be different.' | |||||||||
Changed: | ||||||||||
< < | The if command 'The if command tests the variable $?. Its syntax is:' | |||||||||
> > | The if command'The if command tests the variable$? . Its syntax is:' | |||||||||
Added: | ||||||||||
> > | ||||||||||
if cmd then cmd1 cmd2 | ||||||||||
Added: | ||||||||||
> > | ... | |||||||||
cmdn else cmd3 cmd4 | ||||||||||
Added: | ||||||||||
> > | ... | |||||||||
cmdm fi | ||||||||||
Added: | ||||||||||
> > | ||||||||||
Changed: | ||||||||||
< < | 'That means: considering that the cmd command has been successfully executed, the commands that compose the set called then (cmd1, cmd2 & cmdn) will be executed. Otherwise, the alternative set of commands (else, composed by the cmd3, cmd4 & cmdM commands) will be executed. The execution will be finished with a fi.' | |||||||||
> > | 'That means: considering that the cmd command has been successfully executed, the commands that compose the set called then (cmd1 , cmd2 , ... & cmdn ) will be executed. Otherwise, the optional set of commands else (composed by the cmd3 , cmd4 , ... & cmdm commands), will be executed. The execution will be finished with a fi .' | |||||||||
Changed: | ||||||||||
< < | 'Let's see how it works, using a small script that includes users at /etc/passwd:' ****************************** ... ****************************** 'Notice that the if command tests the grep command (that's its purpose). If the if command succeeds (in the case above, that means: if the user - whose name is in $1 - is found at /etc/passwd) the set of commands called then is executed. Otherwise, the instructions of the set called else are executed (that means that a new if tests whether the useradd command works or not). If something does not work out fine, an error message is exhibited.' | |||||||||
> > | 'Let's see how it works, using a small script that includes users at /etc/passwd :'
$ cat incusu
#!/bin/bash
# Version 1
if grep ^$1 /etc/passwd
then
echo User \'$1\' already exists
else
if useradd $1
then
echo User \'$1\' included at /etc/passwd
else
echo "We have problems. Are you root?"
fi
fi
'Notice that the if command tests the grep command (that's its purpose). If the if command succeeds (in the case above, that means: if the user - whose name is in $1 - is found at /etc/passwd ) the then set of commands is executed (in this example, only the echo command). Otherwise, the instructions of the else set are executed, where new if tests whether the useradd command works including the user $1 in /etc/passwd or not, in this case an error message is exhibited asking if the gay is root.' | |||||||||
'Let's check the command, firstly trying to execute it with a pre existent user:' | ||||||||||
Changed: | ||||||||||
< < | ****************************** ... ****************************** | |||||||||
> > |
$ incusu jneves
jneves:x:54002:1001:Julio Neves:/home/jneves:/bin/bash
User 'jneves' already exists
| |||||||||
'As we've seen a few times, an undesirable line was added by the output of the grep command. In order to avoid that problem, we should desviate the output of that command to /dev/null, like this:' | ||||||||||
Changed: | ||||||||||
< < | ****************************** ... ****************************** | |||||||||
> > |
$ cat incusu
#!/bin/bash
# Version 2
if grep ^$1 /etc/passwd > /dev/null # or: if grep -q ^$1 /etc/passwd
then
echo User \'$1\' already exists
else
if useradd $1
then
echo User \'$1\' included at /etc/passwd
else
echo "We have problems. Are you root?"
fi
fi
| |||||||||
'Now, let a normal user (not the root) test it:' | ||||||||||
Changed: | ||||||||||
< < | ****************************** ... ****************************** 'Wow... that error was not supposed to occur! In order to avoid it, let's desviate the useradd error output to /dev/null, like this:' ****************************** ... ****************************** 'After doing those changes, and executing a su (becoming root), let's see how it works:' ****************************** ... ****************************** | |||||||||
> > |
$ incusu JohnNobody
./incusu[6]: useradd: not found
We have problems. Are you root?
'Wow... that error was not supposed to occur! In order to avoid it, let's desviate the useradd error output to /dev/null , like this:'
$ cat incusu
#!/bin/bash
# Version 3
if grep ^$1 /etc/passwd > /dev/null # or: if grep -q ^$1 /etc/passwd
then
echo User \'$1\' already exists
else
if useradd $1 2> /dev/null
then
echo User \'$1\' included at /etc/passwd
else
echo "We have problems. Are you root?"
fi
fi
'After doing those changes, and executing a su - (becoming root), let's see how it works:'
$ incusu xalaskero
User 'xalaskero' included at /etc/passwd
| |||||||||
'Once again:' | ||||||||||
Changed: | ||||||||||
< < | ****************************** ... ****************************** | |||||||||
> > |
$ incusu xalaskero
User 'xalaskero' already exists
| |||||||||
'See? As I told you, as long as we talk and drink, our programming skills are improving. Let's see how we can enhance our music software:' ****************************** ... |
Line: 1 to 1 | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Added: | |||||||||||||||||||||||||||||||||
> > | Pub Talk Part III
|
Main options of the tr command | |
---|---|
-d char |
removes the characters char from the string |
option | meaning |
-s n |
compresses n occurrences of the string into one |
i
for a
.'
'Suppose that at a certain point of my script, the operator is asked to press y
or n
(y=es or =n=o), and its answer is stored at the variable =$Resp
. The content of that file could be capitalized or not, so, in order to avoid many tests to find out whether it is N
, n
, Y
, y
, I simply do the following:'
n
or a y
.'
'If my file FileIn
is all written in small letters and I wish to convert them into capital letters, what can I do?'
'Take a look: I have used the notation A-Z
so that I would not need to write ABCDEF....YZ
. Other notations that could be used were those we call escape sequences (which are common to other languages, like C) whose meaning you'll see below:'
Escape Sequences | ||
---|---|---|
\\ | Inverted dash | \0134 |
Sequence | Meaning | Octal |
\t | Tab | \011 |
\n | New line |
\012 |
\v | Vertical Tab | \013 |
\f | Form Feed | \014 |
\r | Carriage Return <^M> | \015 |