• Home   /  
  • Archive by category "1"

Ksh Array Assignment In C

An array is a variable containing multiple values may be of same type or of different type.  There is no maximum limit to the size of an array, nor any requirement that member variables be indexed or assigned contiguously. Array index starts with zero.

In this article, let us review 15 various array operations in bash.

This article is part of the on-going Bash Tutorial series. For those who are new to bash scripting, get a jump-start from the Bash Scripting Introduction tutorial.

1. Declaring an Array and Assigning values

In bash, array is created automatically when a variable is used in the format like,

name[index]=value
  • name is any name for an array
  • index could be any number or expression that must evaluate to a number greater than or equal to zero.You can declare an explicit array using declare -a arrayname.
$ cat arraymanip.sh #! /bin/bash Unix[0]='Debian' Unix[1]='Red hat' Unix[2]='Ubuntu' Unix[3]='Suse' echo ${Unix[1]} $./arraymanip.sh Red hat

To access an element from an array use curly brackets like ${name[index]}.

2. Initializing an array during declaration

Instead of initializing an each element of an array separately, you can declare and initialize an array by specifying the list of elements (separated by white space) with in a curly braces.

Syntax: declare -a arrayname=(element1 element2 element3)

If the elements has the white space character, enclose it with in a quotes.

#! /bin/bash $cat arraymanip.sh declare -a Unix=('Debian' 'Red hat' 'Red hat' 'Suse' 'Fedora');

declare -a declares an array and all the elements in the parentheses are the elements of an array.

3. Print the Whole Bash Array

There are different ways to print the whole elements of the array. If the index number is @ or *, all members of an array are referenced. You can traverse through the array elements and print it, using looping statements in bash.

echo ${Unix[@]} # Add the above echo statement into the arraymanip.sh #./t.sh Debian Red hat Ubuntu Suse

Referring to the content of a member variable of an array without providing an index number is the same as referring to the content of the first element, the one referenced with index number zero.

4. Length of the Bash Array

We can get the length of an array using the special parameter called $#.

${#arrayname[@]} gives you the length of the array.

$ cat arraymanip.sh declare -a Unix=('Debian' 'Red hat' 'Suse' 'Fedora'); echo ${#Unix[@]} #Number of elements in the array echo ${#Unix} #Number of characters in the first element of the array.i.e Debian $./arraymanip.sh 4 6

5. Length of the nth Element in an Array

${#arrayname[n]} should give the length of the nth element in an array.

$cat arraymanip.sh #! /bin/bash Unix[0]='Debian' Unix[1]='Red hat' Unix[2]='Ubuntu' Unix[3]='Suse' echo ${#Unix[3]} # length of the element located at index 3 i.e Suse $./arraymanip.sh 4

6. Extraction by offset and length for an array

The following example shows the way to extract 2 elements starting from the position 3 from an array called Unix.

$cat arraymanip.sh Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux'); echo ${Unix[@]:3:2} $./arraymanip.sh Suse Fedora

The above example returns the elements in the 3rd index and fourth index. Index always starts with zero.

7. Extraction with offset and length, for a particular element of an array

To extract only first four elements from an array element . For example, Ubuntu which is located at the second index of an array, you can use offset and length for a particular element of an array.

$cat arraymanip.sh #! /bin/bash Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux'); echo ${Unix[2]:0:4} ./arraymanip.sh Ubun

The above example extracts the first four characters from the 2nd indexed element of an array.

8. Search and Replace in an array elements

The following example, searches for Ubuntu in an array elements, and replace the same with the word ‘SCO Unix’.

$cat arraymanip.sh #!/bin/bash Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux'); echo ${Unix[@]/Ubuntu/SCO Unix} $./arraymanip.sh Debian Red hat SCO Unix Suse Fedora UTS OpenLinux

In this example, it replaces the element in the 2nd index ‘Ubuntu’ with ‘SCO Unix’. But this example will not permanently replace the array content.

9. Add an element to an existing Bash Array

The following example shows the way to add an element to the existing array.

$cat arraymanip.sh Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux'); Unix=("${Unix[@]}" "AIX" "HP-UX") echo ${Unix[7]} $./arraymanip.sh AIX

In the array called Unix, the elements ‘AIX’ and ‘HP-UX’ are added in 7th and 8th index respectively.

10. Remove an Element from an Array

unset is used to remove an element from an array.unset will have the same effect as assigning null to an element.

$cat arraymanip.sh #!/bin/bash Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux'); unset Unix[3] echo ${Unix[3]}

The above script will just print null which is the value available in the 3rd index. The following example shows one of the way to remove an element completely from an array.

$ cat arraymanip.sh Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux'); pos=3 Unix=(${Unix[@]:0:$pos} ${Unix[@]:$(($pos + 1))}) echo ${Unix[@]} $./arraymanip.sh Debian Red hat Ubuntu Fedora UTS OpenLinux

In this example, ${Unix[@]:0:$pos} will give you 3 elements starting from 0th index i.e 0,1,2 and ${Unix[@]:4} will give the elements from 4th index to the last index. And merge both the above output. This is one of the workaround to remove an element from an array.

11. Remove Bash Array Elements using Patterns

In the search condition you can give the patterns, and stores the remaining element to an another array as shown below.

$ cat arraymanip.sh #!/bin/bash declare -a Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora'); declare -a patter=( ${Unix[@]/Red*/} ) echo ${patter[@]} $ ./arraymanip.sh Debian Ubuntu Suse Fedora

The above example removes the elements which has the patter Red*.

12. Copying an Array

Expand the array elements and store that into a new array as shown below.

#!/bin/bash Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux'); Linux=("${Unix[@]}") echo ${Linux[@]} $ ./arraymanip.sh Debian Red hat Ubuntu Fedora UTS OpenLinux

13. Concatenation of two Bash Arrays

Expand the elements of the two arrays and assign it to the new array.

$cat arraymanip.sh #!/bin/bash Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux'); Shell=('bash' 'csh' 'jsh' 'rsh' 'ksh' 'rc' 'tcsh'); UnixShell=("${Unix[@]}" "${Shell[@]}") echo ${UnixShell[@]} echo ${#UnixShell[@]} $ ./arraymanip.sh Debian Red hat Ubuntu Suse Fedora UTS OpenLinux bash csh jsh rsh ksh rc tcsh 14

It prints the array which has the elements of the both the array ‘Unix’ and ‘Shell’, and number of elements of the new array is 14.

14. Deleting an Entire Array

unset is used to delete an entire array.

$cat arraymanip.sh #!/bin/bash Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux'); Shell=('bash' 'csh' 'jsh' 'rsh' 'ksh' 'rc' 'tcsh'); UnixShell=("${Unix[@]}" "${Shell[@]}") unset UnixShell echo ${#UnixShell[@]} $ ./arraymanip.sh 0

After unset an array, its length would be zero as shown above.

15. Load Content of a File into an Array

You can load the content of the file line by line into an array.

#Example file $ cat logfile Welcome to thegeekstuff Linux Unix $ cat loadcontent.sh #!/bin/bash filecontent=( `cat "logfile" `) for t in "${filecontent[@]}" do echo $t done echo "Read file content!" $ ./loadcontent.sh Welcome to thegeekstuff Linux Unix Read file content!

In the above example, each index of an array element has printed through for loop.

Recommended Reading

Bash 101 Hacks, by Ramesh Natarajan. I spend most of my time on Linux environment. So, naturally I’m a huge fan of Bash command line and shell scripting. 15 years back, when I was working on different flavors of *nix, I used to write lot of code on C shell and Korn shell. Later years, when I started working on Linux as system administrator, I pretty much automated every possible task using Bash shell scripting. Based on my Bash experience, I’ve written Bash 101 Hacks eBook that contains 101 practical examples on both Bash command line and shell scripting. If you’ve been thinking about mastering Bash, do yourself a favor and read this book, which will help you take control of your Bash command line and shell scripting.

If you enjoyed this article, you might also like..



Tagged as:Bash Array String, Bash Arrays, Bash Script Array, Bash Scripting Tutorial, Bash Tutorial, Echo Array, Linux Array, Unix Array

Ksh Scripting


Contents

Principle of Script
Variables
Branching
Looping
Commandline Arguments
Comparisons
Variable Manipulations
Ksh Regular Expressions
Functions
Data Redirection
Pipes
Coprocesses
Read Input from User and from Files
Special Variables
Action on Success or Failure of a Command
Trivial Calculations
Numerical Calculations using "bc"
"grep"
"sed"
"awk"
"perl"


Principle of Script

Defining the Shell Type

To make a ksh script (which is a ksh program) crate a new file with a starting line like:
#!/usr/bin/ksh
It is important that the path to the ksh is propper and that the line doesn not have more than 32 characters. The shell from which you are starting the script will find this line and and hand the whole script over to to ksh. Without this line the script would be interpreted by the same typ of shell as the one, from which it was started. But since the syntax is different for all shells, it is necessary to define the shell with that line.

Four Types of Lines

A script has four types of lines: The shell defining line at the top, empty lines, commentary lines starting with a # and command lines. See the following top of a script as an example for these types of lines:

#!/usr/bin/ksh # Commentary...... file=/path/file if [[ $file = $1 ]];then command fi

Start and End of Script

The script starts at the first line and ends either when it encounters an "exit" or the last line. All "#" lines are ignored.

Start and End of Command

A command starts with the first word on a line or if it's the second command on a line with the first word after a";'.
A command ends either at the end of the line or whith a ";". So one can put several commands onto one line:

print -n "Name: "; read name; print ""


One can continue commands over more than one line with a "\" immediately followed by a newline sign which is made be the return key:

grep filename | sort -u | awk '{print $4}' | \ uniq -c >> /longpath/file

Name and Permissions of Script File

The script mus not have a name which is identical to a unix command: So the script must NOT be called "test"!
After saveing the file give it the execute permissions with: chmod 700 filename.


Variables

Filling in

When filling into a variable then one uses just it's name: state="US" and no blanks. There is no difference between strings and numbers: price=50.

Using

When using a variable one needs to put a $ sign in front of it: print $state $price.

Arrays

Set and use an array like:

arrname[1]=4To fill in
print ${arraname[1]}To print out
${arrname[*]}Get all elements
${#arrname[*]}Get the number of elements

Declaration

There are happily no declarations of variables needed in ksh. One cannot have decimals only integers.


Branching

if then fi

if [[ $value -eq 7 ]];then print "$value is 7" fior: if [[ $value -eq 7 ]] then print "$value is 7" fior: if [[ $value -eq 7 ]];then print "$value is 7";fi

if then else fi

if [[ $name = "John" ]];then print "Your welcome, ${name}." else print "Good bye, ${name}!" fi

if then elif then else fi

if [[ $name = "John" ]];then print "Your welcome, ${name}." elif [[ $name = "Hanna" ]];then print "Hello, ${name}, who are you?" else print "Good bye, ${name}!" fi

case esac

case $var in john|fred) print $invitation;; martin) print $declination;; *) print "Wrong name...";; esac

Looping

while do done

while [[ $count -gt 0 ]];do print "\$count is $count" (( count -= 1 )) done

until do done

until [[ $answer = "yes" ]];do print -n "Please enter \"yes\": " read answer print "" done

for var in list do done

for foo in $(ls);do if [[ -d $foo ]];then print "$foo is a directory" else print "$foo is not a directory" fi done

continue...break

One can skip the rest of a loop and directly go to the next iteration with: "continue".

while read line do if [[ $line = *.gz ]];then continue else print $line fi done

One can also prematurely leave a loop with: "break".

while read line;do if [[ $line = *!(.c) ]];then break else print $line fi done

Command Line Arguments

(Officially they are called "positional parameters")

The number of command line arguments is stored in $# so one can check
for arguments with:

if [[ $# -eq 0 ]];then print "No Arguments" exit fi

The single Arguments are stored in $1, ....$n and all are in $* as one string. The arguments cannot
directly be modified but one can reset the hole commandline for another part of the program.
If we need a first argument $first for the rest of the program we do:

if [[ $1 != $first ]];then set $first $* fi

One can iterate over the command line arguments with the help of the shift command. Shift indirectly removes the first argument.

until [[ $# -qe 0 ]];do # commands .... shift done

One can also iterate with the for loop, the default with for is $*:

for arg;do print $arg done

The program name is stored in $0 but it contains the path also!


Comparisons

To compare strings one uses "=" for equal and "!=" for not equal.
To compare numbers one uses "-eq" for equal "-ne" for not equal as well as "-gt" for greater than
and "-lt" for less than.

if [[ $name = "John" ]];then # commands.... fi if [[ $size -eq 1000 ]];then # commands.... fi

With "&&" for "AND" and "||" for "OR" one can combine statements:

if [[ $price -lt 1000 || $name = "Hanna" ]];then # commands.... fi if [[ $name = "Fred" && $city = "Denver" ]];then # commands.... fi

Variable Manipulations

Removing something from a variable

Variables that contain a path can very easily be stripped of it: ${name##*/} gives you just the filename.
Or if one wants the path: ${name%/*}. % takes it away from the left and # from the right.
%% and ## take the longest possibility while % and # just take the shortest one.

Replacing a variable if it does not yet exits

If we wanted $foo or if not set 4 then: ${foo:-4} but it still remains unset. To change that we use:
${foo:=4}

Exiting and stating something if variable is not set

This is very important if our program relays on a certain vaiable: ${foo:?"foo not set!"}

Just check for the variable

${foo:+1} gives one if $foo is set, otherwise nothing.


Ksh Regular Expressions

Ksh has it's own regular expressions.
Use an * for any string. So to get all the files ending it .c use *.c.
A single character is represented with a ?. So all the files starting with any sign followed bye 44.f can be fetched by: ?44.f.

Especially in ksh there are quantifiers for whole patterns:

?(pattern) matches zero or one times the pattern.
*(pattern) matches any time the pattern.
+(pattern) matches one or more time the pattern.
@(pattern) matches one time the pattern.
!(pattern) matches string without the pattern.

So one can question a string in a variable like: if [[ $var = fo@(?4*67).c ]];then ...


Functions

Description

A function (= procedure) must be defined before it is called, because ksh is interpreted at run time.
It knows all the variables from the calling shell except the commandline arguments. But has it's
own command line arguments so that one can call it with different values from different places in
the script. It has an exit status but cannot return a value like a c funcition can.

Making a Function

One can make one in either of the following two ways:

function foo { # commands... } foo(){ # commands... }

Calling the Function

To call it just put it's name in the script: foo. To give it arguments do: foo arg1 arg2 ...
The arguments are there in the form of $1...$n and $* for all at once like in the main code.
And the main $1 is not influenced bye the $1 of a particular function.

Return

The return statement exits the function imediately with the specified return value as an exit status.


Data Redirection

General

Data redirection is done with the follwoing signs: "> >> < <<". Every program has at least a

standardinput, standardoutput and standarderroroutput. All of these can be redirected.

Command Output to File

For writing into a new file or for overwriting a file do: command > file

For appending to a file do: command >> file

Standard Error Redirection

To redirect the error output of a command do: command 2> file

To discard the error alltogether do: command 2>/dev/null

To put the error to the same location as the normal output do: command 2>&1

File into Command

If a program needs a file for input over standard input do: command < file

Combine Input and Output Redirection

command < infile > outfile
command < infile > outfile 2>/dev/null

Commands into Program ( Here Document )

Every unix command can take it's commands from a text like listing with:

command <<EOF
input1
input2
input3
EOF

From eof to eof all is feeded into the above mentioned command.


Pipes

For a serial processing of data from one command to the next do:
command1 | command2 | command3 ...
e.g. last | awk '{print $1}' | sort -u.


Coprocesses

One can have one background process with which one can comunicate with read -p and print -p. It is started with command |&. If one uses: ksh |& then this shell in the background will do everything for us even telnet and so on: print -p "telnet hostname".


Read Input from User and from Files

Read in a Variable

From a user we read with: read var. Then the users can type something in. One should first print something like: print -n "Enter your favorite haircolor: ";read var; print "". The -n suppresses the newline sign.

Read into a File Line for Line

To get each line of a file into a variable iteratively do:

{ while read myline;do # process $myline done } < filename

To catch the output of a pipeline each line at a time in a variable use:

last | sort | { while read myline;do # commands done }

Special Variables

$# Number of arguments on commandline.
$? Exit status of last command.
$$ Process id of current program.
$! Process id of last backgroundjob or background function.
$0 Program name including the path if started from another directory.
$1..n Commandline arguments, each at a time.
$* All commandline arguments in one string.



Action on Success or on Failure of a Command

If one wants to do a thing only if a command succeded then: command1 && command2. If the second command has to be performed only if the first one failed, then: command1 || command2.


Trivial Calculations

Simpe calculations are done with either a "let" in front of it or within (( ... )). One can increment a variable within the (( )) without a "$": (( a+=1 )) or let a+=1.


Numerical Calculations using "bc"

For bigger caluculations one uses "bc" like: $result=$(print "n=1;for(i=1;i<8;i++)n=i*n;n"|bc)


"grep"

Search for the occurence of a pattern in a file: grep 'pattern' file. If one just wants to know how often soemthing occurs in a file, then: grep -c 'pattern file. This can be used in a script like:
if [[ $(grep -c 'pattern' file) != 0 ]];then ......;fi. The condition is fullfilled if the pattern was found.


"sed"

Sed means stream line editor. It searches like grep, but is then able to replace the found pattern. If you want to change all occurences of "poor" with "rich", do: sed -e 's/poor/rich/g' filename. Or what is often seen in software packages, that have to be compiled after getting a propper configuration, is a whole file stuffed with replacements patterns like: /@foo@/s;;king;g. This file with inumerable lines like that has to be given to sed with: sed -f sedscript filename. It then precesses each line from file with all the sed commands in the sedscript. (Of course sed can do much more:-))


"awk"

Awk can find and process a found line with several tools: It can branch, loop, read from files and also print out to files or to the screen, and it can do arithmetics.
For example: We have a file with lines like: Fred 300 45 70 but hundreds of them. But some lines have a "#" as the first sign of them and we have to omit these ones for both, processing and output. And we want to have lines as output like: 415 Fred where 415 is the sum of 300, 45 and 70. Then we call on awk:

awk '$1 !~ /^#/ && $0 ~ /[^ ]/ {print $2+$3+$4,"\t",$1}' filename.

This ignores lines with a "#" at the beginning of the first field and also blank lines. It then prints the desired sum and the $1 ist only printed after a tab. This is the most trivial use of awk only.

Check my AWK programming introduction bye clicking on this sentence!


"perl"

Perl is a much richer programming language then ksh, but still one can do perl commands from within a ksh script. This might touch Randal, but it's true. Let's say you want to remove all ^M from a file, then take perl for one line in your ksh script:

perl -i -ep 's/\015//g' filename.

Perl can do an infinite amount of things in many different ways. For anything bigger use perl instead of a shell script.

Check my PERL programming introduction bye clicking on this sentence!


Email: kistler@gmx.net


One thought on “Ksh Array Assignment In C

Leave a comment

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *