Edit Text Files in Red Hat Enterprise Linux

Red Hat Enterprise LinuxBeginner
Practice Now

Introduction

In this lab, you will gain essential skills for managing text files and customizing your shell environment in Linux. You will learn how to redirect standard output and error streams to files, combine different streams, and construct powerful command pipelines to automate tasks.

Furthermore, you will explore the basics of editing text files using Vim, a widely used and powerful text editor. Finally, you will learn to configure and utilize shell variables and aliases to personalize your command-line experience and enhance productivity.

Redirect Standard Output to Files

In this step, you will learn how to redirect the standard output of commands to files. This is a fundamental skill in Linux system administration, allowing you to capture command results for later analysis, logging, or further processing.

The shell uses special file descriptors to manage input and output. The most common ones are:

  • 0: Standard Input (stdin) - Typically from the keyboard.
  • 1: Standard Output (stdout) - Typically to the terminal screen.
  • 2: Standard Error (stderr) - Typically to the terminal screen for error messages.

We will focus on redirecting stdout in this section.

Overwriting a File with >

The > operator redirects the standard output of a command to a specified file. If the file does not exist, it will be created. If the file already exists, its contents will be overwritten.

Let's start by creating a simple text file with the current date and time.

  1. First, ensure you are in your home directory's project folder.

    cd ~/project
    
    [labex@host project]$
    
  2. Now, use the date command and redirect its output to a new file named current_datetime.txt.

    date > current_datetime.txt
    

    This command will execute date, but instead of printing the date to your terminal, it will save it into current_datetime.txt.

  3. Verify the content of the file using the cat command.

    cat current_datetime.txt
    
    Mon Day XX HH:MM:SS AM/PM TimeZone YYYY
    

    The output will show the current date and time, similar to the example above.

  4. Now, let's try redirecting the output of echo to the same file. This will overwrite the previous content.

    echo "This is a new line of text." > current_datetime.txt
    
  5. Check the file content again.

    cat current_datetime.txt
    
    This is a new line of text.
    

    As you can see, the original date and time were replaced by the new line of text.

Appending to a File with >>

The >> operator redirects the standard output of a command to a specified file, appending the new content to the end of the file. If the file does not exist, it will be created.

Let's append more content to our current_datetime.txt file.

  1. Append another line of text to current_datetime.txt.

    echo "This line is appended." >> current_datetime.txt
    
  2. View the file's content.

    cat current_datetime.txt
    
    This is a new line of text.
    This line is appended.
    

    Notice that the new line was added after the existing content.

  3. Let's append the current date and time again.

    date >> current_datetime.txt
    
  4. Check the file content one more time.

    cat current_datetime.txt
    
    This is a new line of text.
    This line is appended.
    Mon Day XX HH:MM:SS AM/PM TimeZone YYYY
    

    The date and time are now at the end of the file.

Redirecting Output of Other Commands

You can redirect the output of almost any command. Let's try redirecting the output of ls and wc.

  1. Redirect the output of ls -l (long listing format) to a file named file_list.txt.

    ls -l > file_list.txt
    
  2. Inspect the content of file_list.txt.

    cat file_list.txt
    
    total 4
    -rw-r--r-- 1 labex labex 80 Jun  4 07:04 current_datetime.txt
    -rw-r--r-- 1 labex labex  0 Jun  4 07:04 file_list.txt
    

    This file now contains the detailed listing of files in your current directory. The exact file sizes and timestamps will vary based on when you run the commands.

  3. Now, let's count the number of lines in file_list.txt using wc -l and redirect that count to another file, line_count.txt.

    wc -l file_list.txt > line_count.txt
    
  4. View the content of line_count.txt.

    cat line_count.txt
    
    3 file_list.txt
    

    The output shows that file_list.txt has 3 lines (including the total line and the two file entries).

This concludes the first part of redirecting standard output. You've learned how to create and overwrite files using > and append to them using >>.

Redirect Standard Error and Combine Streams

In this step, you will learn how to redirect standard error (stderr) and how to combine stdout and stderr into a single stream. This is crucial for managing error messages generated by commands, allowing you to log them or discard them as needed.

Recall that stderr is file descriptor 2. We use 2> to redirect error messages.

Redirecting Standard Error to a File

Sometimes, commands produce error messages that you want to capture separately from their standard output.

  1. Ensure you are in your ~/project directory.

    cd ~/project
    
    [labex@host project]$
    
  2. Let's try to list the contents of a non-existent directory. This will generate an error message.

    ls non_existent_directory
    
    ls: cannot access 'non_existent_directory': No such file or directory
    

    You can see the error message printed directly to the terminal.

  3. Now, let's redirect this error message to a file named errors.log.

    ls non_existent_directory 2> errors.log
    

    This time, you won't see the error message on your terminal.

  4. Check the content of errors.log.

    cat errors.log
    
    ls: cannot access 'non_existent_directory': No such file or directory
    

    The error message is now stored in the file.

Discarding Standard Error

Often, you might want to run a command that produces noisy error messages that you don't care about. In such cases, you can redirect stderr to /dev/null. /dev/null is a special device file that discards all data written to it.

  1. Try the ls command with the non-existent directory again, but this time, discard the error.

    ls non_existent_directory 2> /dev/null
    

    You will see no output on the terminal, and no error message is saved to a file.

Combining Standard Output and Standard Error

There are situations where you want to capture both stdout and stderr into the same file. This can be done in a few ways.

Method 1: > file 2>&1

This method redirects stdout to a file, and then redirects stderr to the same location as stdout. The order 2>&1 is important: it means "redirect file descriptor 2 (stderr) to the same place as file descriptor 1 (stdout)".

  1. Let's create a command that produces both standard output and standard error. We'll use find to search for a file in a directory where we have permissions and in a directory where we don't.

    find ~/project /root -name "current_datetime.txt" > combined_output.log 2>&1
    

    Here, find ~/project -name "current_datetime.txt" will produce stdout (if found), and find /root -name "current_datetime.txt" will likely produce stderr due to permission issues.

  2. Examine the combined_output.log file.

    cat combined_output.log
    
    /home/labex/project/current_datetime.txt
    find: ‘/root’: Permission denied
    

    You can see both the successful output (the path to the file) and the error message are captured in the same file.

Method 2: &> file (Bash specific)

Bash provides a shorthand for combining stdout and stderr to a file: &>. This is equivalent to > file 2>&1.

  1. Let's try the same find command using the &> shorthand.

    find ~/project /root -name "file_list.txt" &> combined_output_shorthand.log
    
  2. Check the content of combined_output_shorthand.log.

    cat combined_output_shorthand.log
    
    /home/labex/project/file_list.txt
    find: ‘/root’: Permission denied
    

    The result is the same as the previous method, demonstrating the convenience of &>.

Appending Combined Streams

Just like with stdout, you can append combined stdout and stderr to a file using >> file 2>&1 or &>> file.

  1. Append more output and errors to combined_output.log.

    find ~/project /root -name "line_count.txt" >> combined_output.log 2>&1
    
  2. View the updated combined_output.log.

    cat combined_output.log
    
    /home/labex/project/current_datetime.txt
    find: ‘/root’: Permission denied
    /home/labex/project/line_count.txt
    find: ‘/root’: Permission denied
    

    The new output and errors are appended to the existing content.

You have now successfully learned how to redirect standard error and how to combine standard output and standard error into a single file. This knowledge is essential for robust scripting and system administration tasks.

Construct and Understand Command Pipelines

In this step, you will learn about command pipelines, a powerful feature in the Linux shell that allows you to chain multiple commands together. The output of one command becomes the input of the next, enabling complex data processing and manipulation.

The pipe operator | (vertical bar) is used to connect commands in a pipeline. It redirects the standard output (stdout) of the command on its left to the standard input (stdin) of the command on its right.

Basic Pipelines

Let's start with a simple example to understand how pipelines work.

  1. Ensure you are in your ~/project directory.

    cd ~/project
    
    [labex@host project]$
    
  2. First, let's list the files in the current directory.

    ls
    
    combined_output.log
    combined_output_shorthand.log
    current_datetime.txt
    errors.log
    file_list.txt
    line_count.txt
    
  3. Now, let's pipe the output of ls to the wc -l command, which counts the number of lines it receives.

    ls | wc -l
    
    6
    

    The ls command lists the files, and its output (each file name on a new line) is fed as input to wc -l, which then counts these lines, effectively telling you how many files/directories are in the current location.

  4. Let's try another common use case: piping ls -l to less for paginated output. This is useful when a command produces too much output to fit on a single screen.

    ls -l /usr/bin | less
    
    total 200000
    -rwxr-xr-x 1 root root 12345 Jan XX HH:MM [filename]
    ... (press 'q' to quit less) ...
    

    The ls -l /usr/bin command lists all files in /usr/bin with detailed information. This output is then sent to less, allowing you to scroll through it page by page. Press q to exit less.

Filtering Output with grep

The grep command is often used in pipelines to filter lines that match a specific pattern.

  1. Let's list all processes running on the system using ps aux and then filter for processes related to bash.

    ps aux | grep bash
    
    labex     1234  0.0  0.1  12345  6789 ?        Ss   HH:MM   0:00 /usr/bin/bash
    labex     5678  0.0  0.0   9876  5432 pts/0    S+   HH:MM   0:00 grep bash
    

    The ps aux command lists all running processes. Its output is piped to grep bash, which then displays only the lines containing the word "bash". You might see two lines: one for your current bash shell and one for the grep command itself.

  2. To exclude the grep command from the output, you can use grep -v (invert match) or refine your pattern. Let's try grep -v grep.

    ps aux | grep bash | grep -v grep
    
    labex     1234  0.0  0.1  12345  6789 ?        Ss   HH:MM   0:00 /usr/bin/bash
    

    Now, only the actual bash process is shown.

Using sort and uniq

sort is used to sort lines of text, and uniq is used to report or omit repeated lines. They are often used together.

  1. Let's create a file with some unsorted, repeated words.

    echo -e "apple\nbanana\napple\norange\nbanana" > fruits.txt
    
  2. View the content of fruits.txt.

    cat fruits.txt
    
    apple
    banana
    apple
    orange
    banana
    
  3. Now, let's sort the lines in fruits.txt.

    cat fruits.txt | sort
    
    apple
    apple
    banana
    banana
    orange
    
  4. To get only the unique sorted words, pipe the output of sort to uniq.

    cat fruits.txt | sort | uniq
    
    apple
    banana
    orange
    

    This pipeline first sorts the lines, then uniq removes duplicate adjacent lines.

The tee Command

The tee command is special in pipelines. It reads standard input, writes it to standard output, and simultaneously writes it to one or more files. It's like a "T" junction in a pipe, allowing data to flow in two directions.

  1. Let's list the files and save the output to ls_output.txt while also displaying it on the screen.

    ls -l | tee ls_output.txt
    
    total 24
    -rw-r--r-- 1 labex labex 123 Jan XX HH:MM combined_output.log
    -rw-r--r-- 1 labex labex 123 Jan XX HH:MM combined_output_shorthand.log
    -rw-r--r-- 1 labex labex 123 Jan XX HH:MM current_datetime.txt
    -rw-r--r-- 1 labex labex 123 Jan XX HH:MM errors.log
    -rw-r--r-- 1 labex labex 123 Jan XX HH:MM file_list.txt
    -rw-r--r-- 1 labex labex 123 Jan XX HH:MM fruits.txt
    -rw-r--r-- 1 labex labex 123 Jan XX HH:MM line_count.txt
    -rw-r--r-- 1 labex labex 0 Jan XX HH:MM ls_output.txt
    

    You will see the ls -l output on your terminal, and a file named ls_output.txt will be created with the same content.

  2. Verify the content of ls_output.txt.

    cat ls_output.txt
    
    total 24
    -rw-r--r-- 1 labex labex 123 Jan XX HH:MM combined_output.log
    ... (same as above) ...
    
  3. You can also use tee -a to append the output to a file.

    echo "--- End of list ---" | tee -a ls_output.txt
    
    --- End of list ---
    

    The line "--- End of list ---" is printed to the terminal and appended to ls_output.txt.

  4. Check the updated ls_output.txt.

    cat ls_output.txt
    
    total 24
    ... (previous ls -l output) ...
    --- End of list ---
    

Pipelines are incredibly versatile and form the backbone of many powerful shell scripts and one-liner commands. By combining simple commands, you can perform complex data transformations efficiently.

Edit Text Files with Vim Basics

In this step, you will learn the fundamental operations of Vim, a powerful and widely used text editor in the Linux environment. Vim operates in different modes, which can be a bit challenging for beginners, but mastering the basics will significantly boost your productivity.

Vim is a modal editor, meaning it has different modes for different tasks:

  • Normal Mode (Command Mode): This is the default mode when you open Vim. In this mode, keystrokes are interpreted as commands (e.g., moving the cursor, deleting text, copying text).
  • Insert Mode: In this mode, anything you type is inserted into the file. You enter Insert Mode from Normal Mode by pressing i (insert at cursor), a (append after cursor), o (open new line below), etc. To return to Normal Mode, press Esc.
  • Visual Mode: This mode allows you to select blocks of text for operations like copying, cutting, or deleting. You enter Visual Mode from Normal Mode by pressing v (character-wise), Shift+V (line-wise), or Ctrl+V (block-wise). Press Esc to return to Normal Mode.
  • Command-Line Mode (Ex Mode): This mode is used for executing commands that typically start with a colon (:), such as saving (:w), quitting (:q), or searching (/). You enter this mode from Normal Mode by pressing :.

Opening and Basic Navigation

  1. Ensure you are in your ~/project directory.

    cd ~/project
    
    [labex@host project]$
    
  2. Open a new file named my_document.txt using vim.

    vim my_document.txt
    

    Your terminal will now display the Vim interface. You are in Normal Mode.

  3. In Normal Mode, you can navigate using the arrow keys or h (left), j (down), k (up), l (right). Since the file is empty, there's not much to navigate yet.

Insert Mode: Adding Text

  1. To start typing, you need to enter Insert Mode. Press i (for insert). You should see -- INSERT -- at the bottom left of your terminal, indicating you are in Insert Mode.

  2. Type the following lines:

    This is the first line.
    This is the second line.
    This is the third line.
    
  3. To exit Insert Mode and return to Normal Mode, press the Esc key. The -- INSERT -- indicator should disappear.

Saving and Quitting

  1. In Normal Mode, to save the file, type :w and press Enter.

    :w
    

    You should see my_document.txt [New] 3L, 60B written at the bottom, confirming the save.

  2. To quit Vim, type :q and press Enter.

    :q
    

    You will be returned to your shell prompt.

  3. Verify the content of my_document.txt using cat.

    cat my_document.txt
    
    This is the first line.
    This is the second line.
    This is the third line.
    

Editing Existing Files

  1. Open my_document.txt again.

    vim my_document.txt
    
  2. In Normal Mode, move your cursor to the beginning of the second line (using j or arrow keys).

  3. Press Shift+V to enter Visual Line Mode. The entire second line will be highlighted.

  4. Press y to "yank" (copy) the selected line.

  5. Move your cursor to the end of the third line (using j or arrow keys).

  6. Press p to "put" (paste) the yanked line below the current line. The second line will now appear again as the fourth line.

  7. Now, let's delete a line. Move your cursor to the fourth line (the one you just pasted).

  8. Press dd (double d) to delete the entire line.

  9. To undo your last change, press u. The deleted line will reappear.

  10. To save and quit in one command, type :wq and press Enter.

    :wq
    
  11. Verify the content of my_document.txt again.

    cat my_document.txt
    
    This is the first line.
    This is the second line.
    This is the third line.
    This is the second line.
    

    The file should now have four lines, with the second line duplicated.

Discarding Changes

Sometimes you make changes and decide you don't want to save them.

  1. Open my_document.txt again.

    vim my_document.txt
    
  2. Enter Insert Mode by pressing i.

  3. Add a new line at the end:

    This line should not be saved.
    
  4. Press Esc to return to Normal Mode.

  5. Try to quit using :q.

    :q
    

    Vim will warn you: E37: No write since last change (add ! to override). This means you have unsaved changes.

  6. To quit without saving, type :q! and press Enter.

    :q!
    

    You will be returned to the shell prompt, and your changes will be discarded.

  7. Verify the content of my_document.txt.

    cat my_document.txt
    
    This is the first line.
    This is the second line.
    This is the third line.
    This is the second line.
    

    The last line you added should not be present.

You have now covered the very basic operations in Vim: opening files, inserting text, navigating, saving, quitting, and discarding changes. These are the essential skills to get started with Vim.

Configure and Use Shell Variables and Aliases

In this step, you will learn how to configure and use shell variables and aliases. These are powerful features that allow you to customize your shell environment, store data, and create shortcuts for frequently used commands, significantly improving your command-line efficiency.

Shell Variables

Shell variables are named entities that store data. They can store numbers, text, or other data that can be used by the shell or by programs executed within the shell.

  1. Ensure you are in your ~/project directory.

    cd ~/project
    
    [labex@host project]$
    
  2. Setting a Local Variable: Let's create a simple variable named MY_MESSAGE.

    MY_MESSAGE="Hello, LabEx!"
    

    Note that there are no spaces around the = sign.

  3. Accessing a Variable: To access the value of a variable, you prepend its name with a $ sign.

    echo $MY_MESSAGE
    
    Hello, LabEx!
    
  4. Variable Expansion with Braces: Sometimes, you need to clearly delimit the variable name, especially when it's followed by other characters. Use curly braces {} for this.

    echo "The message is: ${MY_MESSAGE}."
    
    The message is: Hello, LabEx!.
    

    If you omit the braces, the shell might interpret MY_MESSAGE. as the variable name, which doesn't exist.

  5. Listing All Set Variables: You can use the set command to list all currently set shell variables and functions. This output can be very long, so it's often piped to less.

    set | less
    
    BASH=/usr/bin/bash
    BASHOPTS=checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:progcomp:promptvars:sourcepath
    ... (press 'q' to quit less) ...
    

    Press q to exit less.

  6. Unsetting a Variable: To remove a variable, use the unset command.

    unset MY_MESSAGE
    
  7. Verify that the variable is no longer set.

    echo $MY_MESSAGE
    
    
    

    You should see an empty line, indicating the variable is unset.

Environment Variables

Environment variables are a special type of shell variable that are inherited by child processes. This means that any program or script launched from your current shell will have access to these variables. They are typically used to configure the environment for applications.

  1. Setting an Environment Variable: Use the export command to make a variable an environment variable.

    export EDITOR=vim
    

    This sets the EDITOR environment variable, which many programs use to determine your preferred text editor.

  2. Listing Environment Variables: Use the env command to list only the environment variables.

    env | grep EDITOR
    
    EDITOR=vim
    
  3. Unexporting a Variable: You can unexport a variable without unsetting it using export -n. This makes it a local variable again.

    export -n EDITOR
    
  4. Verify it's no longer an environment variable.

    env | grep EDITOR
    
    
    

    You should see no output. However, it's still a local variable:

    echo $EDITOR
    
    vim
    
  5. To completely remove it, use unset.

    unset EDITOR
    

Shell Aliases

Aliases are shortcuts for commands. They allow you to define a new command that expands to a longer command or a sequence of commands. This is very useful for frequently used commands with many options.

  1. Creating an Alias: Let's create an alias for ls -l to make it shorter.

    alias ll='ls -l'
    

    Note the single quotes around the command to ensure it's treated as a single string.

  2. Using an Alias: Now, you can simply type ll instead of ls -l.

    ll
    
    total 24
    -rw-r--r-- 1 labex labex 123 Jan XX HH:MM combined_output.log
    ... (output of ls -l) ...
    
  3. Listing Aliases: Use the alias command without any arguments to see all defined aliases.

    alias
    
    alias ll='ls -l'
    

    You might see other default aliases depending on your shell configuration.

  4. Creating a More Complex Alias: You can also create aliases for commands with arguments or multiple commands.

    alias myip='ip a | grep "inet " | grep -v "127.0.0.1" | awk "{print \$2}" | cut -d/ -f1'
    

    Here, myip will show your primary IP address. Note the \$2 to escape the $ sign so it's passed to awk and not interpreted by the shell when the alias is defined.

  5. Test the myip alias.

    myip
    
    172.17.0.2
    

    (Your IP address may vary)

  6. Unsetting an Alias: To remove an alias, use the unalias command.

    unalias ll
    
  7. Verify that the alias is removed.

    alias
    
    alias myip='ip a | grep "inet " | grep -v "127.0.0.1" | awk "{print \$2}" | cut -d/ -f1'
    

    ll should no longer be in the list.

Shell variables and aliases are temporary and will be lost when you close your terminal session. To make them permanent, you need to add them to your shell's configuration files (e.g., ~/.bashrc or ~/.profile), which will be covered in more advanced topics.

Summary

In this lab, you learned fundamental Linux command-line skills essential for managing text files and the shell environment. You began by mastering output redirection, specifically using > to overwrite files and >> to append content, allowing you to capture command results for logging or further processing. You also explored redirecting standard error (2>) and combining standard output and error (&>) to manage all command output effectively.

Furthermore, you gained proficiency in constructing and understanding command pipelines using the | operator, enabling you to chain commands and process data sequentially. You were introduced to basic text editing with Vim, covering essential commands for inserting, saving, and quitting files. Finally, you learned how to configure and use shell variables for storing data and creating aliases to simplify frequently used commands, enhancing your command-line efficiency and customization.