---
# System prepended metadata

title: Bash Script Questions

---

# Question 1:

Write a script to convert the even index of a input string to uppercase.

For example:

INPUT - hello
OUTPUT - HeLlO

## Solution 1:

1. Bash

```
#!/bin/bash

convert_even_indices_to_uppercase() {
    input_string="$1"
    result=""
    for ((i = 0; i < ${#input_string}; i++)); do
        if ((i % 2 == 0)); then
            result="${result}${input_string:i:1}"
        else
            result="${result}${input_string:i:1}"
        fi
    done
    echo "$result"
}

# Get user input
read -p "Enter a string: " input_string

# Call the function to convert even indices to uppercase
result_string=$(convert_even_indices_to_uppercase "$input_string")

# Print the result
echo "Result: $result_string"
```

2. Python:

```
def convert_even_indices_to_uppercase(input_string):
    result = ''
    for i in range(len(input_string)):
        if i % 2 == 0:
            result += input_string[i].upper()
        else:
            result += input_string[i]
    return result

# Get user input
input_string = input("Enter a string: ")

# Call the function to convert even indices to uppercase
result_string = convert_even_indices_to_uppercase(input_string)

# Print the result
print("Result:", result_string)
```

3. Rust:

```
use std::io;

fn convert_even_indices_to_uppercase(input_string: &str) -> String {
    let mut result = String::new();
    for (i, c) in input_string.chars().enumerate() {
        if i % 2 == 0 {
            result.push(c.to_ascii_uppercase());
        } else {
            result.push(c);
        }
    }
    result
}

fn main() {
    let mut input_string = String::new();

    println!("Enter a string: ");
    io::stdin()
        .read_line(&mut input_string)
        .expect("Failed to read line");

    let input_string = input_string.trim(); // Remove newline character

    let result_string = convert_even_indices_to_uppercase(input_string);

    println!("Result: {}", result_string);
}
```

4. Golang:

```
#!/usr/bin/env go run

package main

import (
	"fmt"
	"os"
	"strings"
)

func convertEvenIndicesToUppercase(inputString string) string {
	var result strings.Builder

	for i, char := range inputString {
		if i%2 == 0 {
			result.WriteRune(char)
		} else {
			result.WriteRune(char)
		}
	}

	return result.String()
}

func main() {
	if len(os.Args) != 2 {
		fmt.Println("Usage: ./convert_even_indices.go <string>")
		os.Exit(1)
	}

	inputString := os.Args[1]

	resultString := convertEvenIndicesToUppercase(inputString)

	fmt.Println("Result:", resultString)
}
```

# Question 2:

Write a script to automate the process of backing up a database. The database is located in the /var/lib/mysql directory, and you want to back it up to a directory called /backups/mysql. Write a script that will check if the /backups/mysql directory exists, and if it doesn't, create it. Then, the script should back up the database to the /backups/mysql directory.

Output can be of two ways:
1. If the backup directory is not present:
```
Creating directory: /backups/mysql
Backing up database to /backups/mysql
Backup complete!
```

2.  If the backup directory is present:
```
Backing up database to /backups/mysql
Backup complete!
```

## Solution 2:

1. Bash:

```
#!/bin/bash

# Check if the /backups/mysql directory exists
if [ ! -d /backups/mysql ]; then
  # Create the directory if it doesn't exist
  mkdir -p /backups/mysql
fi

# Back up the database to the /backups/mysql directory
mysqldump -u root -p password database_name > /backups/mysql/database_name.sql
```

2. Python:

```
import os

# Define the source and destination directories
db_source_dir = "/var/lib/mysql"
backup_dest_dir = "/backups/mysql"

# Check if the backup directory exists, and create it if it doesn't
if not os.path.exists(backup_dest_dir):
    os.makedirs(backup_dest_dir)
    print(f"Creating directory: {backup_dest_dir}")

# Backup the database to the destination directory
print(f"Backing up database to {backup_dest_dir}")
# You can add the backup process specific to your database system here

# Simulating a backup process (replace with your actual database backup commands)
# For example: os.system("mysqldump -u <username> -p<password> <database_name> > {}/backup.sql".format(backup_dest_dir))

print("Backup complete!")
```

3. Rust:

```
use std::fs;
use std::process::Command;

fn main() {
    // Define the source and destination directories
    let db_source_dir = "/var/lib/mysql";
    let backup_dest_dir = "/backups/mysql";

    // Check if the backup directory exists, and create it if it doesn't
    if !backup_dest_dir_exists(backup_dest_dir) {
        create_backup_dir(backup_dest_dir);
        println!("Creating directory: {}", backup_dest_dir);
    }

    // Backup the database to the destination directory
    println!("Backing up database to {}", backup_dest_dir);
    // You can add the backup process specific to your database system here

    // Simulating a backup process (replace with your actual database backup commands)
    // For example: run_backup_command("mysqldump -u <username> -p<password> <database_name> > {}/backup.sql", backup_dest_dir);

    println!("Backup complete!");
}

fn backup_dest_dir_exists(path: &str) -> bool {
    fs::metadata(path).is_ok()
}

fn create_backup_dir(path: &str) {
    fs::create_dir_all(path).expect("Failed to create directory");
}

fn run_backup_command(command: &str, dest_dir: &str) {
    let command = command.replace("{}", dest_dir);
    Command::new("sh").arg("-c").arg(&command).output().expect("Failed to run backup command");
}
```

4. Golang:

```
package main

import (
	"fmt"
	"os"
	"os/exec"
)

func main() {
	// Define the source and destination directories
	dbSourceDir := "/var/lib/mysql"
	backupDestDir := "/backups/mysql"

	// Check if the backup directory exists, and create it if it doesn't
	if !backupDestDirExists(backupDestDir) {
		createBackupDir(backupDestDir)
		fmt.Printf("Creating directory: %s\n", backupDestDir)
	}

	// Backup the database to the destination directory
	fmt.Printf("Backing up database to %s\n", backupDestDir)
	// You can add the backup process specific to your database system here

	// Simulating a backup process (replace with your actual database backup commands)
	// For example: runBackupCommand("mysqldump -u <username> -p<password> <database_name> > %s/backup.sql", backupDestDir)

	fmt.Println("Backup complete!")
}

func backupDestDirExists(path string) bool {
	_, err := os.Stat(path)
	return err == nil
}

func createBackupDir(path string) {
	err := os.MkdirAll(path, 0755)
	if err != nil {
		fmt.Printf("Failed to create directory: %v\n", err)
	}
}

func runBackupCommand(command string, destDir string) {
	cmd := exec.Command("sh", "-c", fmt.Sprintf(command, destDir))
	err := cmd.Run()
	if err != nil {
		fmt.Printf("Failed to run backup command: %v\n", err)
	}
}
```

# Question 3:

You are given a directory named "files" that contains text files with various extensions (e.g., .txt, .log, .md). Your task is to write a script that accomplishes the following:

- Searches for all text files (files with extensions .txt, .log, .md) in the "files" directory.
- Counts the total number of lines in each text file.
- Prints the filename along with the corresponding line count for each text file.

For example, if you have three text files named "file1.txt" (with 100 lines), "file2.md" (with 50 lines), and "file3.log" (with 75 lines), the output of your script should be:

```
file1.txt: 100 lines
file2.md: 50 lines
file3.log: 75 lines
```

## Solution 3:

1. Bash:

```
#!/bin/bash

# Directory containing text files
files_dir="files"

# Check if the directory exists
if [ ! -d "$files_dir" ]; then
  echo "Error: The directory '$files_dir' does not exist."
  exit 1
fi

# Search for text files with extensions .txt, .log, and .md in the directory
text_files=$(find "$files_dir" -type f \( -name "*.txt" -o -name "*.log" -o -name "*.md" \))

# Check if there are any text files
if [ -z "$text_files" ]; then
  echo "No text files found in the directory '$files_dir'."
  exit 0
fi

# Loop through each text file and count lines
for file in $text_files; do
  # Extract filename without the path
  filename=$(basename "$file")
  
  # Count lines in the file
  line_count=$(wc -l < "$file")
  
  # Print the result
  echo "$filename: $line_count lines"
done
```

2. Pyhton:

```
import os

directory = "files"

for filename in os.listdir(directory):
    if filename.endswith(".txt") or filename.endswith(".log") or filename.endswith(".md"):
        with open(os.path.join(directory, filename)) as file:
            line_count = sum(1 for line in file)
        print(f"{filename}: {line_count} lines")
```

3. Rust:

```
use std::fs;
use std::path::Path;

fn main() {
    let directory = "files";

    if let Ok(entries) = fs::read_dir(directory) {
        for entry in entries {
            if let Ok(entry) = entry {
                let path = entry.path();
                if path.is_file() {
                    if let Some(extension) = path.extension() {
                        if extension == "txt" || extension == "log" || extension == "md" {
                            if let Ok(lines) = count_lines(&path) {
                                println!("{}: {} lines", path.display(), lines);
                            }
                        }
                    }
                }
            }
        }
    }
}

fn count_lines(file_path: &Path) -> Result<usize, std::io::Error> {
    let contents = std::fs::read_to_string(file_path)?;
    Ok(contents.lines().count())
}
```

4. Golang:

```
package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

func main() {
	directory := "files"

	files, err := ioutil.ReadDir(directory)
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, file := range files {
		if file.IsDir() {
			continue
		}

		extension := strings.ToLower(filepath.Ext(file.Name()))
		if extension == ".txt" || extension == ".log" || extension == ".md" {
			lineCount, err := countLines(filepath.Join(directory, file.Name()))
			if err == nil {
				fmt.Printf("%s: %d lines\n", file.Name(), lineCount)
			}
		}
	}
}

func countLines(filePath string) (int, error) {
	data, err := ioutil.ReadFile(filePath)
	if err != nil {
		return 0, err
	}

	lines := strings.Split(string(data), "\n")
	return len(lines), nil
}
```

# Question 4:

Write a Bash script that will parse a log file and generate a report of the most common errors. The report should include the error message, the number of times the error occurred, and the date and time of the first occurrence.

## Solution 4:

1. Pyhton:

```
import re

def parse_log_file(log_file):
  """Parses a log file and returns a dictionary of error messages and their counts."""

  error_counts = {}

  with open(log_file, "r") as f:
    for line in f:
      error_message = re.search(r"\[error\](.*)", line)
      if error_message:
        error_message = error_message.group(1)
        if error_message not in error_counts:
          error_counts[error_message] = 1
        else:
          error_counts[error_message] += 1

  return error_counts

def generate_report(error_counts):
  """Generates a report of the most common errors."""

  print("Most common errors in {}:".format(log_file))
  for error_message, count in sorted(error_counts.items(), key=lambda x: x[1], reverse=True):
    print("{}: {} occurrences (first occurrence on {})".format(error_message, count, error_counts[error_message][:10]))

if __name__ == "__main__":
  log_file = "/var/log/my_application.log"

  error_counts = parse_log_file(log_file)
  generate_report(error_counts)
```
