Sunday, 29 January 2012

wc


wc
wc is a very useful utility which can count lines, characters, words, bytes etc in a plain text file
or standard input. In shell scripts, It helps to  store a value for the total lines of a file or output of
a command  into a variable for subsequent use. The examples below  show how these things can be achieved.

Example 1)
To  get  the counts of lines,  words  and  bytes of a file  use wc as follows.

/home/mark$ wc    Bulk-SMS-file.txt
 45      140      990------------------------------> No   of   bytes
 |              |---------->  No  of  Words                   
No of lines                                                   
                                


 The individual values can be retrieved as field through awk , but wc provides options.

wc   -l      :   Total   Lines

wc   -w    :   Total   words

wc    -c     :  Total   bytes

wc   -k     :  Total   characters

The wc  command considers a word to be a string of characters of non-zero length which are delimited by a white space and  lines are counted when  newline characters occur.


Example 2)
Using  wc  on multiple files.

/home/mark$ ls  file_list-201111*
file_list-20111105.txt
file_list-20111113.txt
file_list-20111120.txt
file_list-20111128.txt

  /home/mark$ wc   -l    file_list-201111*
  98164   file_list-20111105.txt
  531665 file_list-20111113.txt
  527303 file_list-20111120.txt
  564207 file_list-20111128.txt
 1721339 total

This  gives  you the  no of lines  in  every file as well as the sum of  all the individual  line counts.

Same command  can be  run without the  -l option to get the counts of various parameters and their totals.

Example 3)
wc   can also count these  values  from standard  output through pipes.

/home/mark$ echo  "I  Love  You" | wc
      1       3      17

Hmm!   wc  achieved  something cool  this time…

Similarly you can use wc  -l  as an alternative to grep  -c.
/home/mark$  grep  –c   tremendous    Director-speech.txt 

Is same as

/home/mark$ grep   tremendous    Director-speech.txt  | wc  -l 


Example 4)
wc  -l   may consume a lot of time on counting  the line numbers when the size of the file is huge.
If  we are sure that every line in a file  contains equal number of characters, there  is a faster method to achieve it.

Assume that  you have a continuous file, i.e. a file which  has same number of characters (or bytes ) in each line.
/home/mark$  ls   -lrt   All_Customers.lst
-rw-r--r--    1 mark   Administ    1321655460912 Dec  16 14:37 All_Customers.lst

/home/mark$  wc   -l   All_Customers.lst
23456898

The following steps explain the method.

Step1)
save the  first thousand lines of the file in a separate  file.
/home/mark$  head   -1000   All_Customers.lst   > All_Customers_1000.lst`

Step2)
get  the ratio of  the  total size of the file to the  line count(1000) of the file.
/home/mark$  ls  -lrt  All_Customers_1000.lst
-rw-r--r--    1 mark   Administ    56344000 Dec  16 14:37 All_Customers.lst

/home/mark$  fsize=` ls  -lrt  All_Customers_1000.lst | awk  ‘{ print  $5}’`
/home/mark$  fratio=`expr   $fsize  /  1000`
/home/mark$  echo  $fratio 
56344

Now ,fratio actually stores the number of bytes per file.

Step3)
Now divide  the total size of  All_Customers.lst with  fratio.
/home/mark$tot_lines=` expr  1321655460912 /  $fsize`
/home/mark$echo  $tot_lines
23456898

Which is same as calculated by wc  -l.
All These steps can be used in a shell script  for any given file of this type.

If   there are multiple files of such types (such  as file_list-201111*)  and all have the same fratio.(defined above),then  you can  write a script to get the similar output  as that of
 wc  –l   file_list-201111*

The script is as shown.
fratio=313
tot_val=0
for stream in `ls file_list-201111*`
do
str=`ls -lrt $stream|awk '{print  $5 " + "}'|tr -d "\n"|sed 's/$/0/'`
val=`echo "($str)/$fratio"|bc`
echo  “$val  $stream "
tot_val=`expr $tot_val + $val`
done
echo  " $tot_val   total " 


Here ,between the output  of ls  giving sizes of all the files ,a ‘ +’  symbol  is placed and 0 at the end and is passed to bc command as an expression whose value (the sum)  is divided by the
ratio  just as explained in the 3 steps above.






















tail


tail

tail command is one of my favourite commands because of  its  usefulness  in viewing the last few lines of a required file and also what is being written into a file ( using –f option).it can also be used to see the progress of cp, mv, tar and other commands.

tail by default shows last ten lines of a file.it can be made to view any last ‘n’ lines where n is a number

Example 1)
to view the last 1000 lines of a huge  script page wise ,
/home/k109$ tail -1000 valuefind.sh | pg
.................
.................. #lines of scripts
...........
.
.
.
.................
Standard input      <--- #here pg waits and asks for you to enter a key before which it displays the next page. This is helpful in analysing a script or debugging it page wise.


Example 2)
To view the file contents while it is being written, use –f option. If an application is writing continuously into a file and to know what is being written, this option can be used.
One disadvantage of this command is however that it cannot be used inside scripts because once
The application stops writing to a file the command does not come out of tail directly  and requires some signal like stop or kill to come out.

    Suppose a file is being written by cp command, you can use tail –f  <destination file> to know
exactly what is being written.

Example 3)
To view the contents of the file starting from a particular line, use  tail + <number>  <file1>
Suppose you have a file  worldsport.txt

/home/k109$cat  worldsport.txt
The game is played on a rectangular field of grass or green artificial turf, with a goal in the middle of each of the short ends. The object of the game is to score by driving the ball into the opposing goal. In general play, the goalkeepers are the only players allowed to touch the ball with their hands or arms, while the field players typically use their feet to kick the ball into position, occasionally using their torso or head to intercept a ball in midair. The team that scores the most goals by the end of the match wins. If the score is tied at the end of the game, either adraw is declared or the game goes into extra time and/or a penalty shootout, depending on the format of the competition.

If it is required to view the file starting from second line,use

/home/k109$tail  +2  worldsport.txt
short ends. The object of the game is to score by driving the ball into the opposing goal. In general play, the goalkeepers are the only players allowed to touch the ball with their hands or arms, while the field players typically use their feet to kick the ball into position, occasionally using their torso or head to intercept a ball in midair. The team that scores the most goals by the end of the match wins. If the score is tied at the end of the game, either adraw is declared or the game goes into extra time and/or a penalty shootout, depending on the format of the competition.

sort


sort
Sort ,  as the name suggests sorts  a file  or output of a command. Various  options  determine the sort criteria  which are called as sort keys. If multiple files are passed as parameters to sort the output of sort is concatenated.
Sorting is done in ascending lexicographic order , I e the way in which it appears in a dictionary. If a file contains numbers and alphabet both,  by default sort  places  the  sorted alphabets  first and then the numbers.

Example1)
Consider a file containing  values as shown.

/home/jones$  cat  flowers.txt
rose
lily
tulip
marigold
hibiscus
Chrysanthemum
/home/jones$  sort   flowers.txt
Chrysanthemum
hibiscus
lily
marigold
rose
tulip

If you want to sort it in reverse order ,use
/home/jones$ sort   -r  flowers.txt
tulip
rose
marigold
lily
hibiscus
Chrysanthemum

Example2)
If you want the sort to to be case insensitive sort  –f must be used.
/home/jones $  cat  flowers.txt
rose
lily
Chrysanthemum
tulip
marigold
Rose
hibiscus
chrysanthemum

To   default sort(without any option) would give
/home/jones $ Sort  flowers.txt
Chrysanthemum
Rose
Chrysanthemum
hibiscus
lily
marigold
rose
tulip

Here it sorted the letters starting with uppercase first and then  sorted  lower case ones, Now  use sort -f
/home/jones $ sort  –f  flowers.txt
Chrysanthemum
chrysanthemum
hibiscus
lily
marigold
Rose
rose
tulip


Example3)
A file may contain duplicate lines, and if you want to remove duplicate files before sorting  , use sort –u
/home/jones $ grep   error  cron.log
error code 45:invalid time
error code 35:Invalid name
error code 45:invalid time
error code 25:Invalid email-id
error code 25:Invalid email-id
error code 35 Invalid name

/home/jones $ grep   error  cron.log | sort  -u
error code 25:Invalid email-id
error code 35:Invalid name
error code 45:invalid time

Example 4)                                                                                     
You require to sort based  on  a  particular field  when they are separated by a delimiter.
/home/jones $ cat  detailed-list.csv
dolphin|mammal|12
giraffe|mammal|7
kingfisher|aves|3
moth|insecta|1
shark|fish|6
viper|reptile|2

Now,  The output of default sort command is
dolphin|mammal|12
giraffe|mammal|7
kingfisher|aves|3
moth|insecta|1

shark|fish|6
viper|reptile|2
it sorted on the basis of first field (separated by ‘|’) in alphabetic order. For a change, you required to sort it based on another column.
/home/jones$ sort  -t   “|”  +1  detailed-list.csv
kingfisher|aves|3
shark|fish|6
moth|insecta|1
dolphin|mammal|12
giraffe|mammal|7
viper|reptile|2

Here  -t  “|”  tells the sort command  do sorting on  fields  delimited by a   “|” character. If you do not use  -t option, sequence of  space  characters is considered as   default delimiter .  “+1”    instructs sort to ignore the first field or sort from second field.

Similarly if you wanted to sort it based on the third column, just using  +2  instead of +1 might not work in the given example. The output of that sort command would be as follows.

/home/jones$ sort  -t  “|”  +2  detailed-list.csv
moth|insecta|1
dolphin|mammal|12
viper|reptile|2
kingfisher|aves|3
shark|fish|6
giraffe|mammal|7
It  sorted the third  column according to its alphabetic value  and not arithmetic value. To do so you must use  -n option

/home/jones$ sort   -n  -t  “|”  +2  detailed-list.csv
moth|insecta|1
viper|reptile|2
kingfisher|aves|3
shark|fish|6
giraffe|mammal|7
dolphin|mammal|12

Example5)
The  sorting based on fields can be achieved using   sort with –k option. consider a file containing numbers.
/home/jones$ cat  num-luck
6758 987 456
2586 324 934
0437 235 417
2586 324 934

Suppose  you wanted to sort  this list  such that sorting should start from 3rd column of 1st field and 4th column of  1st  field. Here fields are separated by  one or more spaces.  Columns here refer to characters.

/home/jones$ sort   -k1.3,1.4   num-luck
2812 624 208
0437 235 417
6758 987 456
2586 324 934

To sort from 2nd column of 1st field and  3rd  column of second field in reverse order,

/home/jones$ sort   -k1.2,2.3r   num-luck
2812 624 208
6758 987 456
2586 324 934
0437 235 417

Similarly, to  sort lines based on 1st and 3rd fields, use
Sort  –k1 –k3  <filename >


Example 6)
You may require to sort a particular file and rewrite the file with the sorted file. A simple  command of the form
Sort  filename  >new_sorted_filename     will not work and is dangerous as it  rewrites it into  an empty file. Use  sort with  –o option.

/home/jones$ sort  -o   flowers.txt    flowers.txt 

The  syntax is  sort  –o  <sorted-file>    <file>

Example 7)
Sort  uses a lot of temporary space  while sorting huge files. and by default it uses  /tmp   directory. If sufficient space was not allocated  to /tmp, then  the command would abort abruptly. so sort provides an option  -T by which you can  use an alternative directory  for storing temporary files.

The sort command  sort  -t   “|”  +1  detailed-list.csv in example 4 can be written as
sort  -t   “|”  +1   -T   /backup/jones     detailed-list.csv.
this will use  /backup/jones    directory   for storing temporary files.