Shell Scripting Tutorial Beginners To Advanced

Shell Scripting Tutorial Beginners To Advanced

Day: 1 Introduction to Shell Scripting

What is a shell script?

A shell script is a script written in a shell programming language, which is typically a command-line interpreter for Unix-like operating systems. It allows you to automate various tasks and execute a series of commands in a specific order.

Here's a simple example of a shell script:

#!/bin/bash

# This is a comment explaining the purpose of the script

# Display a greeting message
echo "Hello, welcome to my dev_Safia Tutorial!"

# Print the current date and time
date

# Create a new directory
mkdir my_directory

# Navigate to the new directory
cd my_directory

# Create a new file
touch my_file.txt

# Write some text to the file
echo "This is some example text." > my_file.txt

# Display the contents of the file
cat my_file.txt

# Remove the file
rm my_file.txt

# Navigate back to the previous directory
cd ..

# Remove the directory
rmdir my_directory

# Display a farewell message
echo "Script execution complete. Goodbye!"

In this example, the script starts with the shebang (#!/bin/bash), which specifies the interpreter (in this case, Bash) to execute the script.

The script then proceeds to execute a series of commands:

  1. Displays a greeting message using the echo command.

  2. Prints the current date and time using the date command.

  3. Creates a new directory using the mkdir command.

  4. Navigates to the newly created directory using the cd command.

  5. Creates a new file using the touch command.

  6. Writes some text to the file using the echo command and input/output redirection (>).

  7. Displays the contents of the file using the cat command.

  8. Removes the file using the rm command.

  9. Navigates back to the previous directory using cd ...

  10. Removes the directory using the rmdir command.

  11. Displays a farewell message using the echo command.

You can save this script in a file with a .sh extension, such as my_script.sh, and execute it by running bash my_script.sh in the terminal.

   Different types of shells (Bash, sh, csh, etc.)

  1. Bash (Bourne Again Shell):

    • Bash is one of the most popular and widely used shells on Unix-like systems. It is the default shell for many Linux distributions.

    • Example: The previous shell script example I provided is written in Bash.

  2. sh (Bourne Shell):

    • The Bourne Shell is one of the oldest and simplest shells available on Unix-like systems. It provides a basic set of features and is compatible with many systems.

    • Example: Consider a simple script named my_script.sh:

        #!/bin/sh
      
        # Display a greeting message
        echo "Hello, world!"
      
        # Print the current working directory
        pwd
      
        # List the files in the current directory
        ls
      

      Running sh my_script.sh will execute the script using the sh shell.

  3. csh (C Shell):

    • The C Shell is another popular shell with a different syntax and feature set compared to the Bourne Shell.

    • Example: Here's a sample script named my_script.csh:

        #!/bin/csh
      
        # Display a greeting message
        echo "Hello, world!"
      
        # Print the current working directory
        pwd
      
        # List the files in the current directory
        ls
      

      Running csh my_script.csh will execute the script using the csh shell.

   Advantages of shell scripting:

Shell scripting offers several advantages, making it a powerful tool for automating tasks and managing system configurations. Here are some of the advantages of shell scripting, along with real-time examples:

  1. Automation: Shell scripts enable the automation of repetitive tasks, saving time and effort. For instance, you can write a shell script to automatically back up files or perform regular system maintenance tasks, such as cleaning up temporary files.

  2. Task Sequencing: Shell scripts allow you to sequence multiple commands and programs together. This enables you to execute a series of actions in a specific order, making complex tasks easier to manage. For example, you can create a script to install and configure a web server, including installing dependencies, configuring settings, and starting the server.

  3. Rapid Prototyping: Shell scripting provides a quick and efficient way to prototype and test ideas. You can easily experiment with different commands and logic to achieve the desired outcome without the need for compiling or extensive coding.

  4. System Administration: Shell scripting is widely used for system administration tasks. It allows administrators to automate system configurations, user management, log analysis, and other administrative tasks. For instance, a script can be created to create user accounts, set permissions, and configure user environments in a batch.

  5. Flexibility: Shell scripting is flexible and can be used with various shells and platforms. It can interact with the operating system, execute system commands, and manipulate files and directories. This flexibility makes shell scripts portable and adaptable to different environments.

  6. Integration: Shell scripts can easily integrate with other tools and languages. You can invoke external programs, call scripts from other scripts, and pass parameters between them. This enables you to leverage the capabilities of different tools and languages within your shell scripts.

Real-Time Example: Suppose you have a project that requires compressing log files older than a certain date and moving them to an archive directory. Instead of manually performing these steps, you can create a shell script to automate the process. The script can use commands like find to locate the files, gzip to compress them, and mv to move them to the archive directory. By running the script regularly through a scheduled task, you can automate the entire process and ensure efficient log file management.

Day: 2 Basic Shell Commands :

Navigating the file system :

basic shell commands that will help you navigate the file system. I'll also include real-time examples to make it easier to understand.

  1. pwd (Print Working Directory): This command shows you the current directory you are in.

    Example: Let's say you open the terminal, and you are currently in the user's home directory. Running pwd will display the path to the home directory, such as /home/username.

  2. ls (List): This command lists the files and directories in the current directory.

    Example: Running ls will display a list of files and directories in the current directory.

  3. cd (Change Directory): This command allows you to change your current directory to another directory.

    Example: If you want to navigate to the "Documents" directory inside your home directory, you can run cd Documents.

  4. mkdir (Make Directory): This command creates a new directory.

    Example: Running mkdir new_directory will create a new directory named "new_directory" in the current directory.

  5. touch (Create File): This command creates a new file.

    Example: Running touch new_file.txt will create a new file named "new_file.txt" in the current directory.

  6. cp (Copy): This command copies files or directories from one location to another.

    Example: To copy a file named "file.txt" from the current directory to the "Documents" directory, you can run cp file.txt Documents/.

  7. mv (Move/Rename): This command moves or renames files or directories.

    Example: To rename a file from "old_name.txt" to "new_name.txt," you can run mv old_name.txt new_name.txt. To move the file to a different directory, you can specify the destination directory in the command.

  8. rm (Remove): This command deletes files or directories.

    Example: Running rm file.txt will delete the file named "file.txt" from the current directory. To delete a directory, you can use the -r option, like rm -r directory.

  9. cat (Concatenate): This command displays the content of a file.

    Example: Running cat file.txt will display the contents of the file named "file.txt" in the terminal.

  10. grep (Global Regular Expression Print): This command searches for a specific pattern in files.

    Example: To search for the word "example" in a file named "text.txt," you can run grep "example" text.txt.

These are just a few basic shell commands to help you navigate the file system. There are many more commands available with various options and functionalities.

   Manipulating files and directories :

basic shell commands for manipulating files and directories, along with real-time examples to help you understand them better. Here are a few commonly used commands:

  1. ls: Lists files and directories in the current directory. Example: ls - Lists all the files and directories in the current directory.

  2. cd: Changes the current directory. Example: cd Documents - Changes the current directory to "Documents".

  3. mkdir: Creates a new directory. Example: mkdir Pictures - Creates a new directory named "Pictures".

  4. touch: Creates an empty file. Example: touch file.txt - Creates an empty file named "file.txt".

  5. cp: Copies files and directories. Example: cp file.txt backup/ - Copies the file "file.txt" to the "backup" directory.

  6. mv: Moves or renames files and directories. Example: mv file.txt documents/ - Moves the file "file.txt" to the "documents" directory.

  7. rm: Removes files and directories. Example: rm file.txt - Deletes the file "file.txt".

  8. rmdir: Removes an empty directory. Example: rmdir empty-dir/ - Deletes the empty directory "empty-dir".

  9. cat: Displays the contents of a file. Example: cat file.txt - Shows the contents of the file "file.txt" in the terminal.

  10. grep: Searches for a pattern in files. Example: grep "keyword" file.txt - Searches for the keyword "keyword" in the file "file.txt".

These are just a few basic shell commands for manipulating files and directories. There are many more commands available, each with its own specific purpose. Learning and understanding these commands will greatly enhance your ability to navigate and manipulate files and directories in the shell.

   Text processing commands (grep, sed, awk) :

Here are some basic shell commands for text processing, including grep, sed, and awk, explained in easy-to-understand language with real-time examples:

  1. grep: Grep stands for "Global Regular Expression Print" and is used to search for patterns within text files.

    Example: Let's say you have a text file named data.txt that contains a list of names. You want to find all the lines in the file that contain the name "John". You can use the following command:

     grep "John" data.txt
    

    This will display all the lines in data.txt that contain the word "John".

  2. sed: Sed stands for "Stream Editor" and is used to perform text transformations on input streams.

    Example: Suppose you have a text file named file.txt with the word "Hello" repeated multiple times. You want to replace all occurrences of "Hello" with "Hi". You can use the following command:

     sed 's/Hello/Hi/g' file.txt
    

    This command will replace all occurrences of "Hello" with "Hi" in the file and display the modified text.

  3. awk: Awk is a versatile command used for pattern scanning and processing.

    Example: Let's say you have a text file named grades.txt that contains student names and their corresponding grades in the format "name:grade". You want to print only the names of students who scored above 90. You can use the following command:

     awk -F ":" '$2 > 90 {print $1}' grades.txt
    

    This command sets the field separator to ":" using -F ":", and then it checks if the second field (grade) is greater than 90. If it is, it prints the first field (name).

These are just a few examples of how you can use grep, sed, and awk for text processing in the shell. Each command has many more features and options that you can explore by referring to their respective documentation or using the man command in the shell (e.g., man grep).

Day : 3 Variables and Data Types :

Variable declaration and assignment :

In shell scripting, variable declaration and assignment allow you to store values that can be used throughout your script. The syntax for declaring and assigning variables in shell scripting is quite simple. Let's look at an example with a real-time scenario:

Suppose you want to write a shell script that calculates the area of a rectangle. You need to take the length and width of the rectangle as inputs, perform the calculation, and store the result in a variable.

Here's how you can declare and assign variables in shell scripting:

#!/bin/bash

# Variable declaration and assignment
length=10
width=5

# Calculation
area=$((length * width))

# Displaying the result
echo "The area of the rectangle is: $area"

In the above example, we declare two variables, length and width, and assign them the values 10 and 5, respectively. We then perform the calculation by multiplying the length and width variables and store the result in the area variable.

Finally, we use the echo command to display the result by concatenating the area variable within the output string.

When you run this script, it will output:

The area of the rectangle is: 50

You can modify the values of length and width to calculate the area of different rectangles without changing the rest of the script. Variables provide flexibility and allow you to reuse and manipulate data in shell scripting.

   Data types (string, integer) :

In shell scripting, variables don't have explicit data types. They are treated as strings by default. However, you can perform operations that treat the values as integers or strings based on the context. Let's take a look at some easy and understandable examples of working with string and integer values in shell scripting:

  1. String Example:
#!/bin/bash

# String variables
name="John"
greeting="Hello"

# Concatenating strings
message="$greeting, $name! How are you?"

# Displaying the message
echo $message

In the above example, we have two string variables, name and greeting, which hold the values "John" and "Hello" respectively. We then concatenate these strings using the $ symbol and store the result in the message variable. Finally, we display the message using the echo command.

The output will be:

Hello, John! How are you?
  1. Integer Example:
#!/bin/bash

# Integer variables
num1=10
num2=5

# Performing arithmetic operations
sum=$((num1 + num2))
difference=$((num1 - num2))
product=$((num1 * num2))
quotient=$((num1 / num2))

# Displaying the results
echo "Sum: $sum"
echo "Difference: $difference"
echo "Product: $product"
echo "Quotient: $quotient"

In this example, we have two integer variables, num1 and num2, with the values 10 and 5 respectively. We perform various arithmetic operations such as addition, subtraction, multiplication, and division using these variables. The results are then stored in separate variables (sum, difference, product, and quotient) using the $(( ... )) syntax. Finally, we display the results using the echo command.

The output will be:

Sum: 15
Difference: 5
Product: 50
Quotient: 2

Even though the variables in shell scripting are treated as strings by default, the shell is capable of performing arithmetic operations by evaluating expressions within double parentheses (( )).

   Environment variables :

In shell scripting, environment variables are special variables that are predefined by the operating system or set by the user. They contain information about the system environment and can be accessed by shell scripts. Let's explore environment variables with an easy-to-understand example:

#!/bin/bash

# Accessing environment variables
echo "Home directory: $HOME"
echo "Username: $USER"
echo "Current working directory: $PWD"
echo "Operating system: $OSTYPE"

In the above example, we use the echo command to display the values of several common environment variables:

  • $HOME: This variable represents the home directory of the current user. It typically stores the path to the user's folder.

  • $USER: This variable holds the username of the current user.

  • $PWD: This variable stores the absolute path of the current working directory. It provides the location where the script is being executed.

  • $OSTYPE: This variable contains the identifier for the operating system type. It specifies the type of operating system being used, such as "linux-gnu" for Linux systems.

When you run this script, it will output something similar to:

Home directory: /home/username
Username: username
Current working directory: /path/to/current/directory
Operating system: linux-gnu

The actual values will depend on your system configuration.

Environment variables are useful for accessing system-related information or storing configuration values that can be shared among different scripts or programs.

Please note that environment variables may vary depending on the operating system and the shell being used. The examples provided here are common environment variables found in Unix-like systems.

Day: 4 Input and Output:

Reading User Input in Shell Scripting:

In shell scripting, you can read user input using the read command. It allows you to prompt the user for input and store their response in a variable. Here's an example:

#!/bin/bash

echo "Enter your name:"
read name
echo "Hello, $name!"

In this example, the echo command is used to display the message "Enter your name:" to the user. The read command then waits for the user to enter their name, and the input is stored in the name variable. Finally, the echo command is used again to print the greeting message, including the user's name.

Outputting Data in Shell Scripting:

To display output in shell scripting, you can use the echo command or simply write the desired content directly in the script. Here's an example:

#!/bin/bash

age=23
echo "Your age is: $age"

In this example, the echo command is used to display the text "Your age is: 23". The value of the age variable is directly embedded in the output by using the $ symbol followed by the variable name.

Real-Time Example:

Let's say you have a shell script called my_script.sh that reads user input and outputs some results. You can run this script in the terminal and provide input and output as needed.

  1. Reading user input: Suppose you want to enter your name as input for my_script.sh. You can run the script and provide the input as follows:
./my_script.sh
Enter your name:
dev_safia
Hello, dev_safia!

The script prompts "Enter your name:" and waits for you to type your name. After pressing Enter, it displays the greeting message using the provided name.

  1. Outputting data: Suppose my_script.sh calculates some results and you want to display them.
#!/bin/bash

result=$((10 + 5))
echo "The result is: $result"

When you run the script, it will output:

The result is: 15

The output displays the calculated result, which in this case is 15.

  • Redirection (stdin, stdout, stderr) in Shell Scripting:

    Redirection in shell scripting refers to the process of changing the default sources or destinations of input and output streams. It allows you to redirect the standard input (stdin), standard output (stdout), and standard error (stderr) of a command or script.

    Here are some examples of redirection in shell scripting:

    1. Redirecting stdin (Input Redirection): You can redirect the standard input of a command or script by using the < symbol followed by the source. The source can be a file or another command.

Example 1: Reading input from a file Suppose you have a file called input.txt containing data that you want to use as input for a script named my_script.sh. You can redirect stdin using the following command:

    ./my_script.sh < input.txt

This command runs my_script.sh and sets the content of input.txt as the input for the script.

Example 2: Piping output from another command as input Suppose you have a command that produces some output, and you want to use that output as input for another command or script. You can use the pipe operator | for this purpose.

    command1 | ./my_script.sh

In this example, the output of command1 is piped (|) as the input for my_script.sh.

Let's say command1 is a simple command that lists the files in the current directory:

    ls

And my_script.sh is a script that expects a list of files as input and performs some operations on them:

    #!/bin/bash

    echo "Received files:"
    while read -r file; do
      echo "$file"
      # Perform some operations on each file
    done

Now, if you use the pipe operator to redirect the output of ls as input to my_script.sh like, this:

    ls | ./my_script.sh

The output of ls (the list of files in the current directory) will be passed as input to my_script.sh. The script will then process each file and display the received files:

    Received files:
    file1.txt
    file2.txt
    file3.txt
    ...

In this example, the pipe operator allows you to connect the output of one command (ls) to the input of another command (my_script.sh), enabling data flow between the two commands and enabling further processing or manipulation of the data in the script.

  1. Redirecting stdout (Output Redirection): You can redirect the standard output of a command or script to a file or another command using the > symbol.

Example 1: Writing output to a file Suppose you want to save the output of a script named my_script.sh to a file called output.txt. You can redirect stdout using the following command:

    ./my_script.sh > output.txt

This command runs my_script.sh and saves the output that would normally be displayed in the console to the output.txt file.

Here's an example to illustrate how this works:

Suppose you have a script called my_script.sh that generates some output:

    #!/bin/bash

    echo "This is some output."
    echo "More output."

If you run the script with output redirection to output.txt like this:

    ./my_script.sh > output.txt

The stdout produced by my_script.sh will be saved to the output.txt file. The contents of output.txt will be:

    This is some output.
    More output.

In this example, the > symbol redirects the stdout of ./my_script.sh to the output.txt file. Instead of displaying the output on the console, it is saved to the file.

  • Example 2: Appending output to a file If you want to append the output to an existing file instead of overwriting it, you can use the >> symbol.

      ./my_script.sh >> output.txt
    

    This command appends the output of my_script.sh to the end of the output.txt file.

    Here's an example to illustrate how this works:

    Suppose you have a script called my_script.sh that generates some output:

      #!/bin/bash
    
      echo "This is some output."
      echo "More output."
    

    If you run the script with output redirection in append mode to output.txt like this:

      ./my_script.sh >> output.txt
    

    The stdout produced by my_script.sh will be appended to the end of the output.txt file, preserving any existing content. The contents of output.txt will be:

      Existing content in output.txt (if any)
      This is some output.
      More output.
    

    In this example, the >> symbol redirects the stdout of ./my_script.sh and appends it to the output.txt file, rather than overwriting its existing contents.

    Using >> for output redirection in append mode is useful when you want to accumulate the output over multiple runs or multiple commands/scripts into the same file, without losing any previously captured information.

    NOTE :

    It's important to note that if you want to overwrite the file and start fresh with each run, you can use > instead of >>. For example, ./my_script.sh > output.txt will overwrite the output.txt file with the latest stdout each time the script is executed.

    Overall, ./my_script.sh >> output.txt allows you to capture and append the stdout of a script or command to a file, preserving its existing contents and creating a log or history of outputs.

    Redirecting stderr (Error Redirection): You can redirect the standard error output of a command or script to a file or another command using the 2> symbol.

    Example 1: Redirecting stderr to a file Suppose you want to save the error messages generated by a script named my_script.sh to an error log file called error.log. You can redirect stderr using the following command:

      ./my_script.sh 2> error.log
    

    This command runs my_script.sh and redirects any error messages to the error.log file.

    Here's an example to illustrate how this works:

    Suppose you have a script called my_script.sh that generates some error messages:

      #!/bin/bash
    
      echo "This is a regular output."
      echo "This is an error." >&2
    

    If you run the script with error output redirection to error.log like this:

      ./my_script.sh 2> error.log
    

    The stderr produced by my_script.sh will be saved to the error.log file. The contents of error.log will be:

      This is an error.
    

    In this example, the 2> symbol redirects the stderr of ./my_script.sh to the error.log file. The regular output is still displayed on the console, but any error messages generated by the script are saved to the file.

    Example 2: Discarding stderr If you want to discard the error messages and prevent them from being displayed or stored, you can redirect stderr to /dev/null.

      ./my_script.sh 2> /dev/null
    

    This command runs my_script.sh and discards any error messages generated by the script.

    Here's an example to illustrate how this works:

    Suppose you have a script called my_script.sh that generates some error messages:

      #!/bin/bash
    
      echo "This is a regular output."
      echo "This is an error." >&2
    

    If you run the script with error output redirection to /dev/null like this:

      ./my_script.sh 2> /dev/null
    

    The stderr produced by my_script.sh is redirected to /dev/null, which means it is discarded and not displayed or saved anywhere.

    In this example, the 2> symbol redirects the stderr of ./my_script.sh to /dev/null, effectively suppressing any error messages generated by the script. The regular output is still displayed on the console, but any error messages are discarded.

    This technique is useful when you want to ignore or silence error messages, especially in cases where you're only interested in the regular output or when you don't want error messages to clutter the console or log files.

    It's important to note that by redirecting stderr to /dev/null, you won't receive any indication of the errors or be able to troubleshoot them. This should be used judiciously and only when you're confident that discarding the errors is appropriate.

    Overall, ./my_script.sh 2> /dev/null allows you to discard or suppress the stderr output of a script or command, effectively ignoring any error messages it generates.

    These examples demonstrate how redirection can be used in shell scripting to control the input sources, output destinations, and error handling of commands and scripts.

DAY: 5 . Conditional Statements

  1. Conditional Statements: Conditional statements allow you to execute different blocks of code based on certain conditions. The most common conditional statement is the "if...else" statement.

Example: Let's say you want to write a program that checks whether a person is old enough to vote. If the person is 18 years or older, they can vote; otherwise, they cannot.

age = 20

if age >= 18:
    print("You are eligible to vote!")
else:
    print("You are not eligible to vote yet.")

Output:

You are eligible to vote!

Explanation: In the example, the if statement checks if the age variable is greater than or equal to 18. If the condition is true, it executes the code block inside the if statement (prints "You are eligible to vote!"). Otherwise, it executes the code block inside the else statement (prints "You are not eligible to vote yet.").

  1. Comparison Operators: Comparison operators are used to compare values and return a Boolean result (True or False) based on the comparison. Here are the common comparison operators:
  • ==: Equal to

  • !=: Not equal to

  • <: Less than

  • >: Greater than

  • <=: Less than or equal to

  • >=: Greater than or equal to

Example: Let's compare two variables, x and y, and check if x is greater than y.

x = 5
y = 3

if x > y:
    print("x is greater than y")
else:
    print("x is not greater than y")

Output:

x is greater than y

Explanation: In this example, the if statement compares the values of x and y using the greater than (>) operator. Since 5 is greater than 3, the condition is true, and it executes the code block inside the if statement.

  1. Logical Operators: Logical operators allow you to combine multiple conditions and create more complex conditions. The three common logical operators are:
  • and: Returns True if both conditions are True.

  • or: Returns True if at least one condition is True.

  • not: Returns the opposite of the condition.

Example: Let's use logical operators to check if a number is between 10 and 20.

number = 15

if number > 10 and number < 20:
    print("The number is between 10 and 20")
else:
    print("The number is not between 10 and 20")

Output:

The number is between 10 and 20

Explanation: In this example, the if statement uses the logical operator and to check if the number is greater than 10 and less than 20. Since 15 satisfies both conditions, the overall condition is true, and it executes the code block inside the if statement.

Day: 6. Loops

  1. For Loops: For loops are used to iterate over a sequence (such as a list, string, or range) a specific number of times. They have a predefined structure:

     for variable in sequence:
         # code block to be executed
    

    Example: Let's say you want to print the numbers from 1 to 5.

     for i in range(1, 6):
         print(i)
    

    Output:

     1
     2
     3
     4
     5
    

The syntax for a for loop in shell scripting is as follows:

for variable in list
do
    # code block to be executed
done

The list can be a sequence of items separated by spaces, or it can be a command that generates a list of items. The variable is a user-defined variable that holds each item from the list for each iteration.

Here's a second real-time example: Let's say you have a directory containing multiple image files, and you want to resize each image using an image processing tool called "convert."

#!/bin/bash

# List all image files in the directory
for image_file in *.jpg
do
    # Resize each image file
    convert "$image_file" -resize 800x600 "$image_file"_resized.jpg
done

In the example above, the script iterates over all the image files with the .jpg extension in the current directory. For each iteration, the script uses the convert command to resize the image file and save it with a new filename appended with "_resized.jpg". This process is repeated for each image file in the directory.

You can modify the example based on your specific needs. For example, you can change the file extension, specify a different command, or perform any action on the items in the list.

By utilizing the for loop in shell scripting, you can efficiently automate repetitive tasks and process multiple items effortlessly.

  1. While Loops: Loops repeatedly execute a block of code as long as a specified condition is true. They have the following structure:

     while condition:
         # code block to be executed
    

    Example: Let's say you want to print the numbers from 1 to 5 using a while loop.

     i = 1
     while i <= 5:
         print(i)
         i += 1
    

    Output:

     1
     2
     3
     4
     5
    

The syntax for a while loop-in shell scripting is as follows:

while condition
do
    # code block to be executed
done

The condition is a test that is evaluated before each iteration of the loop. If the condition is true, the code block is executed, and the loop continues. If the condition is false, the loop terminates, and the program execution continues with the next statement after the done keyword.

Here's a real-time example: Let's say you want to count down from 5 to 1 and display a message for each count.

#!/bin/bash

counter=5
while [ $counter -gt 0 ]
do
    echo "Countdown: $counter"
    counter=$((counter - 1))
done

echo "Blast off!"

In the example above, the script initializes a variable counter with a value of 5. The while loop is executed as long as the condition [ $counter -gt 0 ] is true, which means the value of counter is greater than 0. Inside the loop, it echoes a message showing the current value of counter, and then decrements counter by 1. This process continues until counter reaches 0.

After the loop, the script echoes "Blast off!" to indicate the completion of the countdown.

You can modify the example based on your specific needs. For example, you can change the initial value of counter, modify the condition, or include additional code inside the loop.

While loops in shell scripting are useful for executing a block of code repeatedly until a certain condition is no longer true. They provide flexibility and control over the flow of your script.

  1. Until Loops: In many programming languages, "until" loops are not a separate construct. However, you can achieve the same functionality using a while loop with a negated condition. The loop continues until the condition becomes true. Here's an example of an "until" loop equivalent to the previous while loop:

     i = 1
     until i > 5:
         print(i)
         i += 1
    

    Output:

      1
      2
      3
      4
      5
    

The syntax for an "until" loop in shell scripting is as follows:

until condition
do
    # code block to be executed
done

The condition is a test that is evaluated before each iteration of the loop. If the condition is false, the code block is executed, and the loop continues. If the condition becomes true, the loop terminates, and the program execution continues with the next statement after the done keyword.

Here's a real-time example: Let's say you want to prompt the user to enter a positive number, and keep prompting until a valid input is provided.

#!/bin/bash

number=0
until [ $number -gt 0 ]
do
    read -p "Enter a positive number: " number
done

echo "You entered: $number"

In the example above, the script initializes the variable number with a value of 0. The until loop is executed as long as the condition [ $number -gt 0 ] is false, which means the value of number is not greater than 0. Inside the loop, it prompts the user to enter a positive number using the read command, and the input is assigned to the variable number. If the input is not a positive number, the loop continues and prompts again. Once a valid positive number is entered, the loop terminates, and the script displays the input value.

You can modify the example based on your specific needs. For instance, you can change the condition, prompt the user for different input, or include additional code inside the loop.

While there isn't a direct "until" loop in shell scripting, using a while loop with a negated condition achieves the same functionality, allowing you to repeatedly execute a block of code until a specific condition becomes true.

  1. Loop Control Statements:

    • Break: The break statement is used to exit a loop prematurely. It is typically used when a certain condition is met, and you want to stop the loop execution immediately.

      Example: Let's say you want to print the numbers from 1 to 10, but stop the loop when the number 6 is encountered.

        for i in range(1, 11):
            print(i)
            if i == 6:
                break
      

      Output:

        1
        2
        3
        4
        5
        6
      
    • Continue: The continue statement is used to skip the remaining code within a loop iteration and move to the next iteration.

      Example: Let's say you want to print the numbers from 1 to 5, but skip printing the number 3.

        for i in range(1, 6):
            if i == 3:
                continue
            print(i)
      

      Output:

        1
        2
        4
        5
      

These examples demonstrate the usage of different types of loops and loop control statements. They provide a basic understanding of how loops work and how you can control their flow using break and continue statements.

Day: 7 . Functions and Subroutines

In shell scripting, functions and subroutines are blocks of reusable code that can be called multiple times within a script. They help in organizing and modularizing code, making it easier to understand, maintain, and update.

Functions: A function is a named block of code that performs a specific task. It can take arguments, execute a set of instructions, and return a value if needed. Functions are defined using the function keyword or by simply declaring the function name followed by parentheses.

Here's an example of a function in shell scripting that calculates the square of a number:

square() {
  local num=$1
  local result=$((num * num))
  echo "The square of $num is $result"
}

In this example, the function square takes an argument num, calculates its square, and prints the result. To call the function, you can simply use its name followed by the arguments in parentheses:

square 5

The output will be: "The square of 5 is 25."

Subroutines: Subroutines in shell scripting are similar to functions but don't have a formal return value. They are used to group a set of instructions that can be executed multiple times within a script without the need for arguments or a return statement.

Let's consider an example of a subroutine in shell scripting that displays a welcome message:

welcome_message() {
  echo "Welcome to the script!"
  echo "This is a subroutine."
  echo "Enjoy scripting!"
}

To invoke the subroutine, you can simply use its name:

welcome_message

Executing this code will display the following output:

Welcome to the script!
This is a subroutine.
Enjoy scripting!

Subroutines are particularly useful when you have a set of instructions that need to be executed multiple times in different parts of your script, providing a way to avoid code duplication.

By utilizing functions and subroutines, you can structure your shell scripts in a more organized and modular way, enhancing readability and maintainability.

Declaring and invoking functions :

  1. Declaring a function: To declare a function, you need to give it a name and define the actions it should perform. Here's an example of a function called greet that prints a greeting message:

     greet() {
       echo "Hello! Welcome to my script."
       echo "I hope you're having a great day!"
     }
    

    In this example, the function greet is defined with the actions to display a greeting message using the echo command.

  2. Invoking a function: To use the function, you simply need to call it by its name. Here's how you can invoke the greet function from the previous example:

     greet
    

    When you execute this code, the function will be invoked, and the greeting message will be displayed on the console:

     Hello! Welcome to my script.
     I hope you're having a great day!
    

    Note that you don't need to provide any arguments when calling this function since it doesn't require any.

Real-time Example: Let's consider a real-time example of a function called calculate_average that calculates the average of three numbers and prints the result:

calculate_average() {
  local num1=$1
  local num2=$2
  local num3=$3
  local sum=$((num1 + num2 + num3))
  local average=$((sum / 3))
  echo "The average of $num1, $num2, and $num3 is: $average"
}

In this example, the calculate_average function takes three arguments: num1, num2, and num3. It calculates their sum, divides it by 3 to get the average, and then displays the result.

To invoke this function, you need to provide three numbers as arguments:

calculate_average 10 20 30

Executing this code will output:

The average of 10, 20, and 30 is: 20

By declaring and invoking functions in your shell script, you can encapsulate reusable pieces of code, making your script more organized, modular, and easier to maintain.

   Passing arguments to functions:

Passing arguments to functions in shell scripting allows you to provide input values to the function, making it more versatile and reusable. Arguments can be accessed within the function to perform specific operations based on the provided values.

Here's an example of a function in shell scripting that adds two numbers:

add_numbers() {
  local num1=$1
  local num2=$2
  local sum=$((num1 + num2))
  echo "The sum of $num1 and $num2 is $sum"
}

In this example, the function add_numbers takes two arguments, num1 and num2. It calculates their sum and prints the result. To call the function and pass arguments, you simply provide the values within parentheses:

add_numbers 5 7

The output will be: "The sum of 5 and 7 is 12."

You can pass any number of arguments to a function by separating them with spaces when calling the function. For example:

my_function arg1 arg2 arg3

Within the function, you can access the passed arguments using the positional parameters: $1 for the first argument, $2 for the second argument, and so on.

It's important to note that arguments are passed by value in shell scripting, which means that the function receives a copy of the argument's value rather than the original variable. Therefore, modifying the argument within the function won't affect the original variable outside the function.

Using arguments in functions enables you to create dynamic and flexible scripts that can perform different operations based on the input values provided when calling the function.

   Returning values from functions:

Returning values from functions in shell scripting allows you to obtain a result or data computed within the function and use it in other parts of your script. Here's an example in easy and understandable language:

Let's say we want to write a function that calculates the sum of two numbers and returns the result. We can define the function as follows:

sum() {
  local num1=$1
  local num2=$2
  local result=$((num1 + num2))
  echo $result
}

In this example, the function sum takes two arguments, num1 and num2. It calculates their sum and stores the result in the result variable. Finally, it uses the echo command to output the result.

To retrieve the returned value from the function, you can assign the function call to a variable. For example:

result=$(sum 5 3)
echo "The sum is: $result"

In this code, the function sum is called with arguments 5 and 3. The returned value, the sum of 5 and 3, is assigned to the result variable. Then, the value is printed with the echo command.

The output will be: "The sum is: 8."

By returning values from functions, you can perform complex calculations, data processing, or any other operations within the function and use the result in different parts of your script. This helps in keeping your code modular and allows for better code reuse.

Day: 8 . Arrays

In shell scripting, an array is a data structure that allows you to store multiple values under a single variable. It is a collection of elements, each identified by an index. Arrays provide a convenient way to organize and access related data in a script.

Let's take an example to illustrate arrays in shell scripting:

Suppose you have a list of fruits that you want to store and manipulate in your shell script. Instead of creating individual variables for each fruit, you can use an array to store all the fruits in a single variable.

Here's an example code snippet:

#!/bin/bash

# Declare an array of fruits
fruits=("Apple" "Banana" "Orange" "Mango")

# Accessing individual elements of the array
echo "First fruit: ${fruits[0]}"
echo "Second fruit: ${fruits[1]}"
echo "All fruits: ${fruits[@]}"

# Modifying array elements
fruits[2]="Grapes"

# Adding elements to the array
fruits+=("Pineapple")

# Looping through the array
echo "All fruits:"
for fruit in "${fruits[@]}"; do
    echo "$fruit"
done

In this example, we first declare an array called fruits and assign it multiple values using parentheses and double quotes. Each fruit is separated by a space. Then, we access individual elements of the array using the index within braces (${fruits[index]}). Note that array indexing starts from 0, so the first element is accessed using ${fruits[0]}.

We can modify array elements by assigning a new value to a specific index. In the example, we change the third fruit from "Orange" to "Grapes" using fruits[2]="Grapes".

To add new elements to the array, we use the += operator. In the code, we add "Pineapple" to the fruits array using fruits+=("Pineapple").

Lastly, we demonstrate looping through the array using a for loop. The "${fruits[@]}" syntax expands to all elements of the array, and we iterate over each fruit, printing it out.

When you run this script, it will display the various fruits and demonstrate the operations you can perform on an array in shell scripting.

Arrays in shell scripting provide a versatile way to work with collections of related data. They are helpful in scenarios where you need to store and manipulate multiple values under a single variable.

Creating and accessing arrays :

Here's an example that demonstrates creating and accessing arrays in shell scripting, with input and output.

#!/bin/bash

# Read input from the user
echo "Enter a list of names (separated by spaces):"
read -r input

# Split the input string into an array
IFS=" " read -ra names <<< "$input"

# Accessing individual elements of the array
echo "First name: ${names[0]}"
echo "Second name: ${names[1]}"
echo "All names: ${names[@]}"

# Looping through the array
echo "All names:"
for name in "${names[@]}"; do
    echo "$name"
done

In this example, the script prompts the user to enter a list of names separated by spaces. The input is then read and stored in the input variable.

Next, we use the read command with the -ra flags to split the input string into an array called names. The IFS variable is set to a space character to specify the delimiter for splitting the string.

We can access individual elements of the array using the index within braces (${names[index]}). In the code, we display the first name using ${names[0]} and the second name using ${names[1]}. To access all the names in the array, we use ${names[@]}.

The script also demonstrates looping through the array using a for loop. We iterate over each name in the names array and print it out.

Here's an example of input and output when running the script:

Input:

Enter a list of names (separated by spaces):
dev_safia john Peter

Output:

First name: dev_safia
Second name: john
All names: dev_safia john Peter
All names:
dev_safia
john
Peter

The script splits the input string "dev_safia John Peter" into individual names and performs operations on the resulting array. It showcases the process of creating and accessing arrays in shell scripting.

   Array manipulation (adding, removing elements):

Let's dive into array manipulation in shell scripting with an example that demonstrates adding and removing elements from an array based on user input.

#!/bin/bash

# Declare an empty array
fruits=()

# Function to add a fruit to the array
add_fruit() {
    fruits+=("$1")
    echo "Added $1 to the array."
}

# Function to remove a fruit from the array
remove_fruit() {
    if [[ ${#fruits[@]} -eq 0 ]]; then
        echo "The array is empty. No fruits to remove."
    else
        index=-1
        for i in "${!fruits[@]}"; do
            if [[ "${fruits[$i]}" = "$1" ]]; then
                index=$i
                break
            fi
        done

        if [[ $index -ge 0 ]]; then
            unset fruits[$index]
            echo "Removed $1 from the array."
        else
            echo "Fruit $1 not found in the array."
        fi
    fi
}

# Display the array
display_array() {
    if [[ ${#fruits[@]} -eq 0 ]]; then
        echo "The array is empty."
    else
        echo "Fruits in the array:"
        for fruit in "${fruits[@]}"; do
            echo "$fruit"
        done
    fi
}

# Main script

echo "Array Manipulation Script"

while true; do
    echo "1. Add a fruit"
    echo "2. Remove a fruit"
    echo "3. Display the array"
    echo "4. Exit"
    read -p "Enter your choice: " choice

    case $choice in
        1)
            read -p "Enter the fruit to add: " new_fruit
            add_fruit "$new_fruit"
            ;;
        2)
            read -p "Enter the fruit to remove: " remove_fruit
            remove_fruit "$remove_fruit"
            ;;
        3)
            display_array
            ;;
        4)
            echo "Exiting the script."
            exit 0
            ;;
        *)
            echo "Invalid choice. Please try again."
            ;;
    esac

    echo
done

In this example, we start with an empty array called fruits. The script presents a menu to the user with options to add a fruit, remove a fruit, display the array, or exit the script.

The add_fruit function takes user input and adds the entered fruit to the fruits array using the += operator.

The remove_fruit function prompts the user to enter a fruit to remove. It searches for the fruit in the array by iterating over the indices using ${!fruits[@]}. If the fruit is found, it uses unset to remove the element from the array. If the fruit is not found, it provides a corresponding message.

The display_array function checks if the array is empty. If it is, it displays a message indicating that the array is empty. Otherwise, it iterates through the array using a for loop and prints each fruit.

The main script implements a loop that continuously displays the menu and performs the selected operation based on user input.

Here's an example of how the script can be used:

Array Manipulation Script
1. Add a fruit
2. Remove a fruit
3. Display the array
4. Exit
Enter your choice: 1
Enter the fruit to add: Apple
Added Apple to the array.

1. Add a fruit
2. Remove a fruit
3. Display the array
4.

 Exit
Enter your choice: 1
Enter the fruit to add: Banana
Added Banana to the array.

1. Add a fruit
2. Remove a fruit
3. Display the array
4. Exit
Enter your choice: 3
Fruits in the array:
Apple
Banana

1. Add a fruit
2. Remove a fruit
3. Display the array
4. Exit
Enter your choice: 2
Enter the fruit to remove: Apple
Removed Apple from the array.

1. Add a fruit
2. Remove a fruit
3. Display the array
4. Exit
Enter your choice: 3
Fruits in the array:
Banana

1. Add a fruit
2. Remove a fruit
3. Display the array
4. Exit
Enter your choice: 4
Exiting the script.

This example demonstrates how the script allows you to add fruits, remove fruits, display the current array contents, and exit the script based on user input.

   Array iteration :

Here's the code snippet that showcases array iteration:

#!/bin/bash

# Declare an array of numbers
numbers=(10 20 30 40 50)

# Variable to store the sum
sum=0

# Loop through the array and calculate the sum
for num in "${numbers[@]}"; do
    sum=$((sum + num))
done

# Print the sum
echo "Sum of numbers: $sum"

In this example, we start by declaring an array called numbers with some numerical values. These values represent the numbers you want to calculate the sum of.

We then initialize a variable called sum to 0, which will store the cumulative sum of the numbers.

Next, we use a for loop to iterate through each element in the numbers array. The "${numbers[@]}" syntax expands to all elements of the array. The loop assigns each element to the variable num, one at a time.

Inside the loop, we update the sum variable by adding the current number to it using the arithmetic expression $((sum + num)). This accumulates the sum as we iterate through the array.

After the loop finishes executing, we print the final sum using the echo command.

Now, let's see the input and output of this script:

Input (array of numbers): 10 20 30 40 50

Output (sum of numbers): Sum of numbers: 150

When you run this script, it will calculate the sum of the numbers in the array and display the result as output. You can modify the array elements or add more numbers to observe different sums.

This example demonstrates how to iterate over an array in shell scripting and perform calculations or operations on its elements. Array iteration allows you to process each element sequentially, enabling you to perform various tasks efficiently.

Day: 9. File Handling

In shell scripting, file handling refers to operations performed on files, such as reading from files, writing to files, and managing file permissions and ownership. Let's explore each of these concepts with easy-to-understand examples.

  1. Reading from files: To read data from a file in shell scripting, you can use the cat or read command. The cat command displays the contents of a file, while the read command reads a file line by line. Here's an example:
#!/bin/bash

filename="example.txt"

# Reading file using 'cat' command
cat $filename

# Reading file using 'read' command
while read line
do
    echo $line
done < $filename

In this example, the script reads the contents of the file "example.txt" using both the cat and read commands.

  1. Writing to files: To write data to a file in shell scripting, you can use the echo or printf command combined with file redirection (> or >>). The > operator overwrites the file with new content, while >> appends content to the end of the file. Here's an example:
#!/bin/bash

filename="example.txt"

# Writing to file using 'echo' command
echo "Hello, World!" > $filename

# Appending to file using 'printf' command
printf "This is a new line." >> $filename

In this example, the script writes the text "Hello, World!" to the file "example.txt" using the echo command and then appends the line "This is a new line." using the printf command.

  1. File permissions and ownership: In shell scripting, you can modify file permissions and ownership using the chmod and chown commands, respectively. Here's an example:
#!/bin/bash

filename="example.txt"

# Changing file permissions to read, write, and execute for the owner
chmod u+rwx $filename

# Changing file ownership to a specific user
chown newuser $filename

In this example, the script sets the file permissions of "example.txt" to read, write, and execute for the owner using chmod. It then changes the file ownership to the user "newuser" using chown.

Remember to make the shell script executable using the command chmod +x script.sh before running it.

Day 10. Error Handling and Debugging

Error handling and debugging in shell scripting is crucial for identifying and resolving issues that may occur during script execution. It involves handling errors gracefully and providing meaningful feedback to users.

  1. Handling Errors and Exceptions: In shell scripting, you can handle errors and exceptions using conditional statements and exit codes. The most commonly used exit codes are 0 (success) and non-zero (failure).

    Here's an example of a script that handles errors by checking the exit code:

     #!/bin/bash
    
     command1
     if [ $? -ne 0 ]; then
         echo "Error: Command1 failed"
         exit 1
     fi
    
     command2
     if [ $? -ne 0 ]; then
         echo "Error: Command2 failed"
         exit 1
     fi
    
     echo "All commands executed successfully"
    

    In this example, if command1 or command2 fails (returns a non-zero exit code), the script displays an error message and exits with a non-zero exit code. Otherwise, it prints "All commands executed successfully".

  2. Debugging Techniques: Debugging shell scripts can be done using various techniques, such as:

    a. Echoing variables and commands: You can use echo statements to print the values of variables and intermediate results to identify any issues. For example:

     #!/bin/bash
    
     variable=10
     echo "The value of variable is: $variable"
    
     result=$(command)
     echo "The result of the command is: $result"
    

    b. Using the set -x option: By adding set -x at the beginning of your script, the shell will print each command before executing it. This can help identify the exact command causing an issue. For example:

     #!/bin/bash
    
     set -x
    
     # Your script commands go here
    
     set +x
    

    c. Adding temporary debug code: You can insert temporary debug code like exit or echo statements at different points in your script to narrow down the problematic area. This helps you identify where the script fails. Once the issue is resolved, you can remove the debug code.

  3. Logging and Error Reporting: Logging and error reporting are essential for troubleshooting and understanding script behavior. You can redirect script output to a log file using the >> operator.

    Here's an example of how to log script output to a file:

     #!/bin/bash
    
     log_file="script.log"
    
     # Redirect output to log file
     exec >> "$log_file"
     exec 2>&1
    
     # Your script commands go here
    
     echo "Script executed successfully"
    

    In this example, the output of the script and any error messages are redirected to the specified log file (script.log). You can examine the log file to analyze the script's execution and identify any errors or issues.

Remember to make the script executable using chmod +x script.sh before running it.

DAY 11. Command-Line Arguments and Options

Command-line arguments and options are essential for controlling the behaviour of shell scripts. Let's explore each aspect with real-time examples.

  1. Accessing Command-Line Arguments: Command-line arguments are values passed to a shell script when it is executed. These arguments provide inputs or instructions to the script. In most scripting languages, including shell scripting, command-line arguments are accessed through special variables.

Example: Consider a script named greeting.sh that takes a name as a command-line argument and prints a personalized greeting.

#!/bin/bash

name=$1
echo "Hello, $name! Welcome to the script."

Command: ./greeting.sh John Output: Hello, John! Welcome to the script.

In the above example, the value passed after the script name (John) is accessed using $1, where $1 represents the first command-line argument.

  1. Option Parsing (getopts): Option parsing allows the script to handle command-line options that modify its behavior. The getopts command is commonly used in shell scripting to parse options.

Example: Consider a script named backup.sh that has two options: -f for specifying a file and -d for specifying a directory to be backed up.

#!/bin/bash

while getopts ":f:d:" option; do
    case $option in
        f)
            file=$OPTARG
            echo "Backing up file: $file"
            ;;
        d)
            directory=$OPTARG
            echo "Backing up directory: $directory"
            ;;
        \?)
            echo "Invalid option: -$OPTARG"
            ;;
    esac
done

Command: ./backup.sh -f myfile.txt -d mydir Output:

Backing up file: myfile.txt
Backing up directory: mydir

In the above example, the getopts command is used to parse options (-f and -d) and their corresponding arguments (myfile.txt and mydir). The colon (:) after each option specifies that an argument is expected.

  1. Argument Validation and Processing: Shell scripts often require validating and processing command-line arguments to ensure correctness and handle unexpected inputs. This can involve checking if the arguments meet certain conditions or performing additional actions based on the arguments provided.

Example: Consider a script named calculator.sh that performs basic arithmetic operations (addition, subtraction, multiplication, and division) based on command-line arguments.

#!/bin/bash

if [ $# -ne 3 ]; then
    echo "Usage: ./calculator.sh <number> <operator> <number>"
    exit 1
fi

num1=$1
operator=$2
num2=$3

case $operator in
    +)
        result=$(($num1 + $num2))
        ;;
    -)
        result=$(($num1 - $num2))
        ;;
    *)
        echo "Invalid operator: $operator"
        exit 1
        ;;
esac

echo "Result: $result"

Command: ./calculator.sh 5 + 3 Output: Result: 8

In the above example, the script first checks if exactly three arguments are provided. If not, it displays a usage message and exits. Then, it assigns the arguments to variables and performs the corresponding operation based on the operator provided.

These examples illustrate the concepts of accessing command-line arguments, option parsing using getopts, and argument validation and processing in shell scripting. By utilizing these techniques, you can create more flexible and powerful shell scripts that can be customized through command-line inputs.

Day 12. Regular Expressions

Regular expressions (regex) are a powerful tool for pattern matching and manipulating text in various programming languages, including shell scripting.

  1. Pattern matching with regex: Regex allows you to search for patterns within text strings. For example, let's say you have a log file and want to find all lines containing the word "error." You can use the grep command with regex:
grep "error" logfile.txt

This command will display all lines in logfile.txt that contain the word "error."

  1. Capturing groups and backreferences: Regex allows you to define capturing groups to extract specific parts of a matched pattern. Capturing groups are enclosed in parentheses. Let's say you have a string containing a date in the format "MM-DD-YYYY," and you want to extract the day (DD) and year (YYYY) separately. You can use capturing groups and backreferences in sed with the -E option to output only the matched part:
echo "Today's date is 06-24-2023." | sed -E 's/.*([0-9]{2})-([0-9]{2})-([0-9]{4}).*/\1 \2 \3/'

The command above will output:

06-24-2023

Regex-based text manipulation: Regex can also be used for text manipulation. Let's say you have a file with a list of email addresses, and you want to extract only the domain names. You can use sed (stream editor) command with regex:

cat emails.txt | sed -E 's/.*@(.*)/\1/'

Assuming emails.txt contains email addresses like john@example.com, the command will output:

example.com

In this example, the regex pattern captures everything after the "@" symbol and replaces the entire line with the captured group \1, which represents the domain name.

These are just a few examples of how regex can be used in shell scripting for pattern matching and text manipulation. Regular expressions offer a vast range of possibilities and become more valuable as you explore and master their usage.

Day 13. Advanced Text Processing

    Advanced usage of grep, sed, and awk:

some advanced text processing techniques using grep, sed, and awk in a shell scripting language. We'll go through each tool and provide real-time examples for data extraction, transformation, text parsing, and pattern recognition.

  1. grep (Global Regular Expression Print):

    • Real-time Example: Let's say we have a log file containing multiple error messages, and we want to extract all the lines containing the word "error" from the file.

        grep "error" logfile.txt
      

      This command will search for the word "error" in the file logfile.txt and display all the matching lines.

  2. sed (Stream Editor):

    • Real-time Example: Suppose we have a CSV file with multiple records and want to replace all occurrences of a specific word with another word. For example, replacing "OpenAI" with "OpenAI Inc." in the file.

        sed 's/OpenAI/OpenAI Inc./g' file.csv
      

      This command will substitute all occurrences of "OpenAI" with "OpenAI Inc." in the file file.csv and display the modified output.

  3. awk:

    • Real-time Example: Let's assume we have a text file containing a list of students and their corresponding scores, separated by a colon. We want to extract only the names of students who scored above 90.

        awk -F':' '$2 > 90 { print $1 }' scores.txt
      

      This command uses awk to specify the field separator as a colon (-F':'). It then checks if the second field (scores) is greater than 90 and prints the corresponding first field (names).

    Data extraction and transformation:

Let's assume we have a text file containing a list of employee records in the following format:

John,Smith,35,Male
Alice,Johnson,28,Female
Mark,Williams,42,Male

Our goal is to extract the first and last names of the employees and transform them into uppercase. Here's how you can achieve this using a shell script:

#!/bin/bash

# Read the file line by line
while IFS=',' read -r first_name last_name age gender
do
  # Convert first and last names to uppercase
  first_name_upper=$(echo "$first_name" | tr '[:lower:]' '[:upper:]')
  last_name_upper=$(echo "$last_name" | tr '[:lower:]' '[:upper:]')

  # Display the transformed data
  echo "First Name: $first_name_upper"
  echo "Last Name: $last_name_upper"
  echo "Age: $age"
  echo "Gender: $gender"
  echo "------------------------"
done < employees.txt

Save the script in a file (e.g., extract_transform.sh), make it executable (chmod +x extract_transform.sh), and run it (./extract_transform.sh). It will process each line of the employees.txt file, extract the first and last names, convert them to uppercase using the tr command, and display the transformed data along with the age and gender.

The output will be:

First Name: JOHN
Last Name: SMITH
Age: 35
Gender: Male
------------------------
First Name: ALICE
Last Name: JOHNSON
Age: 28
Gender: Female
------------------------
First Name: MARK
Last Name: WILLIAMS
Age: 42
Gender: Male
------------------------

This example demonstrates how you can extract specific fields from a file, perform transformations, and display the processed data using a shell script. Feel free to customize and enhance this script based on your specific data extraction and transformation requirements.

Text parsing and pattern recognition:

Let's assume we have a log file containing multiple log entries in the following format:

[2023-06-20 09:15:32] INFO: User login successful. Username: john_doe
[2023-06-20 10:30:12] ERROR: Invalid input received. IP: 192.168.1.10
[2023-06-21 14:55:20] WARNING: Disk space low. Utilization: 85%

Our goal is to parse the log entries and identify any errors (log entries starting with "ERROR"). Here's how you can achieve this using a shell script:

#!/bin/bash

# Read the log file line by line
while IFS= read -r line
do
  # Check if the line starts with "ERROR"
  if [[ $line == "ERROR"* ]]; then
    # Display the error log entry
    echo "Error Log Entry: $line"
    echo "------------------------"
  fi
done < logfile.txt

Save the script in a file (e.g., parse_logs.sh), make it executable (chmod +x parse_logs.sh), and run it (./parse_logs.sh). It will process each line of the logfile.txt file, check if the line starts with "ERROR" using the [[ $line == "ERROR"* ]] conditional statement, and display the error log entry if found.

The output will be:

Error Log Entry: [2023-06-20 10:30:12] ERROR: Invalid input received. IP: 192.168.1.10
------------------------

This example demonstrates how you can parse a text file, identify specific patterns (in this case, log entries starting with "ERROR"), and perform actions based on the identified patterns using a shell script. You can modify and extend this script to handle different patterns and perform various actions accordingly.

Day. 14 Advanced Control Structures

Advanced control structures in shell scripting refer to complex control flow mechanisms that allow for more intricate program logic. These structures enhance the flexibility and functionality of shell scripts.

   Case statements:

Case statements in shell scripting provide a way to evaluate multiple conditions or options and execute different blocks of code based on the matched condition. It offers a concise and readable syntax to handle complex decision-making scenarios.

Here's an example of using a case statement in shell scripting with user input and corresponding output:

#!/bin/bash

echo "Enter a country:"
read country

case $country in
    "USA")
        echo "Capital: Washington, D.C."
        echo "Currency: US Dollar"
        ;;
    "France")
        echo "Capital: Paris"
        echo "Currency: Euro"
        ;;
    "Japan")
        echo "Capital: Tokyo"
        echo "Currency: Japanese Yen"
        ;;
    "Australia")
        echo "Capital: Canberra"
        echo "Currency: Australian Dollar"
        ;;
    *)
        echo "Information not available for the entered country."
        ;;
esac

In this example, the user is prompted to enter a country. The script then matches the input against different cases using a case statement. Based on the entered country, the script provides specific information such as the capital and currency. If the entered country is not listed, it displays a default message.

Input:

Enter a country:
France

Output:

Capital: Paris
Currency: Euro

In this case, since "France" is entered as the country, the script matches it with the corresponding case and displays the capital and currency of France.

Select statements:

The select statement in shell scripting provides a way to create menus for users to make selections. It simplifies the process of presenting options and handling user choices.

The select statement is used to create a menu system in shell scripts. It displays a numbered list of options to the user and waits for their input. Once the user selects an option, the script executes the corresponding code block.

Let me provide you with an example that mimics the behaviour of a select statement.

#!/bin/bash

options=("Option 1" "Option 2" "Option 3" "Exit")

PS3="Select an option: "

select choice in "${options[@]}"
do
    case $choice in
        "Option 1")
            echo "You selected Option 1."
            ;;
        "Option 2")
            echo "You selected Option 2."
            ;;
        "Option 3")
            echo "You selected Option 3."
            ;;
        "Exit")
            echo "Exiting the script."
            break
            ;;
        *)
            echo "Invalid option. Please try again."
            ;;
    esac
done

In this example, the script presents a menu-like interface to the user using the select loop. The user can choose an option by entering the corresponding number. The script then matches the selected option using a case statement and performs the corresponding action or exits the script if "Exit" is chosen.

Here's a sample interaction:

1) Option 1
2) Option 2
3) Option 3
4) Exit
Select an option: 2
You selected Option 2.

1) Option 1
2) Option 2
3) Option 3
4) Exit
Select an option: 4
Exiting the script.

The select loop provides an intuitive way to create menus and handle user choices in shell scripting, even though shell scripting itself doesn't have a dedicated select statement.

Advanced loop techniques:

Advanced loop techniques in shell scripting provide more flexibility and control during repetitive tasks. They allow you to iterate over a range of values, process elements in an array, or conditionally control the loop flow. Here's an easy and understandable explanation of some advanced loop techniques in shell scripting:

  1. For Loop: The for loop is used to iterate over a range of values or elements in an array.

Syntax:

for variable in values
do
    # Code to be executed for each value
done
  • variable represents a variable that takes each value from the specified values.

  • values can be a range (e.g., 1..5) or an array of elements.

Example 1: Iterating over a range of values

#!/bin/bash

for i in {1..5}
do
    echo "Number: $i"
done

This script iterates over the range 1 to 5 and prints each number.

Example 2: Iterating over an array

#!/bin/bash

fruits=("Apple" "Banana" "Orange")

for fruit in "${fruits[@]}"
do
    echo "Fruit: $fruit"
done

This script iterates over each element in the array fruits and displays the name of each fruit.

  1. While Loop: The while loop repeatedly executes a block of code as long as a specified condition is true.

Syntax:

while condition
do
    # Code to be executed
done
  • condition represents a logical expression that determines whether the loop should continue or not.

Example:

#!/bin/bash

count=1

while [ $count -le 5 ]
do
    echo "Count: $count"
    count=$((count + 1))
done

This script initializes count to 1 and prints its value while it is less than or equal to 5. The count is incremented within the loop.

  1. Until Loop: The until loop repeatedly executes a block of code until a specified condition becomes true.

Syntax:

until condition
do
    # Code to be executed
done
  • condition represents a logical expression that determines whether the loop should continue or not. The loop continues until the condition becomes true.

Example:

#!/bin/bash

count=1

until [ $count -gt 5 ]
do
    echo "Count: $count"
    count=$((count + 1))
done

This script initializes count to 1 and prints its value until it becomes greater than 5. The count is incremented within the loop.

These advanced loop techniques provide you with more control and options for repetitive tasks in shell scripting. They make it easier to handle complex scenarios where you need to iterate over a range, process elements in an array, or control the loop based on specific conditions.