Shell I/O Redirection, The Shell Filters and Shell Expansion
Tags: linux, ubuntu, 100daysofcode, codenewbie
Published: 2022-09-07 23:22:58

## 
**INTRODUCTION**
There are many reasons why you should learn about i/o redirection, the shell filters, and shell expansion. For one, these concepts are essential for anyone who wants to be able to use the command line effectively. Without a understanding of how these things work, it will be difficult to make full use of the potential of the command line. Additionally, learning about these topics will give you a better understanding of how Linux works under the hood. Finally, being knowledgeable about i/o redirection, shell filters, and shell expansion will make it easier for you to troubleshoot any issues that might come up when using the command line.

## **I/O Redirections** 
 
Redirection is a feature in Linux such that you can change the standard input/output devices when executing a command. the basic workflow of any Linux command is it takes an input and gives an output

the command performs all terminal-related activity with three files that the shell makes available to every command, this includes:
                 
1. standard input  (stdnin)       **<** is information inputted into the terminal through the keyboard or input device.
2. standard output   (stdout)   **>**is the information outputted after a process is run.
3. standard error    (stderror) is an error message outputted by a failed process.

**output redirection**.

The **">"** symbol is used for output  redirection

```
root@537302f1e700:~/fruits# ls -l > listings               
root@537302f1e700:~/fruits# cat listings                   
total 0                                                    
-rw-r--r-- 1 root root 0 Sep  7 13:46 apple                
-rw-r--r-- 1 root root 0 Sep  7 13:46 Apple                
-rw-r--r-- 1 root root 0 Sep  7 13:49 banana               
-rw-r--r-- 1 root root 0 Sep  7 13:48 Banana               
-rw-r--r-- 1 root root 0 Sep  7 13:47 cherry 
```

The output of **ls** on redirecting will be stored in the listings file, and this is how one can redirect a command.

when one uses the **">"** operator to redirect to a file containing the same name, the information in the file is overwritten.

```
root@537302f1e700:~/fruits# echo " welcome " > listings      
root@537302f1e700:~/fruits# cat listings                     
 welcome   
```

echo welcome > listings has overwritten the existing file.

in order for one not to be able to overwrite a file one should get to append on redirecting, and this is done by using the output append operator  **>>*

```
root@537302f1e700:~/fruits# echo " welcome " > listings      
root@537302f1e700:~/fruits# cat listings                     
 welcome                                                     
root@537302f1e700:~/fruits# echo "welcome again" >> listings 
root@537302f1e700:~/fruits# cat listings                     
 welcome                                                     
welcome again 
```

**input redirection**
The  '<' symbol is used for (stdin) redirection
this is brought about by
i.e 

```
$ wc -l users
2 users
$
```

```
$ wc -l < users
2
$

```
Note that there is a difference in the output produced by the two forms of the wc command. In the first case, the name of the file users is listed with the line count; in the second case, it is not.

In the first case, wc knows that it is reading its input from the file users. In the second case, it only knows that it is reading its input from standard input so it does not display file name.


## **filters in Linux**


Filters are programs that take in plain text as standard input and transform it into a meaningful format that hence returns it as standard output.
These includes:

**1. cat**

it displays the text of the file line by line
                 cat [path]

```
root@537302f1e700:~/fruits# cat list                       
apple                                                      
mango                                                      
banana                                                     
oranges  
```

**2. head**


It displays the first n lines of a file, if the number of lines is not specified then by default it prints the first 10 lines
head [lines-to-print] [path]

```
root@537302f1e700:~/fruits# head list                      
apple                                                      
mango                                                      
banana                                                     
oranges                                                    
Melon                                                      
mandarin                                                   
Avocado                                                    
coconut                                                    
Cherry                                                     
lime                                                       
root@537302f1e700:~/fruits# head -3 list                   
apple                                                      
mango                                                      
banana                                                     
root@537302f1e700:~/fruits#                                
                            
```



**3. tail**

This is the reverse order of head, but it returns the lines from bottom to up

```
root@537302f1e700:~/fruits# tail list                      
mango                                                      
banana                                                     
oranges                                                    
Melon                                                      
mandarin                                                   
Avocado                                                    
coconut                                                    
Cherry                                                     
lime                                                       
Longan                                                     
root@537302f1e700:~/fruits# tail -3 list                   
Cherry                                                     
lime                                                       
Longan  
```

**4. sort**

It is used to sort a file, arranging the records in a particular order 

             sort [options] path

By default: Lines with a number will appear before lines starting with a letter
   

```
root@537302f1e700:~/fruits# sort list                      
1mango                                                     
20melon                                                    
3lime                                                      
apple                                                      
Avocado                                                    
banana                                                     
Cherry                                                     
coconut
```
                

**Options with sort function**

**-v**   it sorts in a reverse order 

**-n**   sorts the file numerical

**-nv**  it sorts a file with numeric data in a reverse order

**-k**   sorts table on basis of any column

**-c**    it is used to check if a file given is already sorted or not 

**-u**    used to sort and remove duplicate

**-m**   used to sort a file on a monthly basis


**5. uniq**
it is used to remove duplicate lines
as with this banana was duplicate and after using the uniq program it removed the duplicate item.
```
root@537302f1e700:~/fruits# cat list                       
apple                                                      
mango                                                      
banana                                                     
banana                                                     
oranges                                                    
Melon                                                      
mandarin                                                   
Avocado                                                    
coconut                                                    
Cherry                                                     
lime                                                       
Longan                                                     
1mango                                                     
3lime                                                      
20melo                                                     
apple                                                      
o                                                          
root@537302f1e700:~/fruits# uniq list                      
apple                                                      
mango                                                      
banana                                                     
oranges  
```

**6. wc**
It gives the number of lines, words, and characters in the the  data 
By default it displays four columnar outputs

```
root@537302f1e700:~/fruits#  wc list                       
 17  17 112 list  
```
     wc [options] [path]
wc stands for word count

With wc one can pass more than one file
i.e 
**Note:** when more than one file is placed in the argument it adds one more line which counts the total

```
root@537302f1e700:~/fruits# wc list melon orange           
 17  17 112 list                                           
  0   0   0 melon                                          
  0   0   0 orange                                         
 17  17 112 total  
```

**wc options**
-l prints the number of lines in a file 

-w  prints the number of words present in a file

-m display count of characters  in a file

-v it displays the version of wc

**some of the applications of of wc command**

To count all the files and folders present in a directory
i.e ls list | wc -l

```
root@537302f1e700:~/fruits# ls list | wc -l                
1 
```

To dispay number of word count only of a file 
i.e wc -w  list  
```
root@537302f1e700:~/fruits# wc -w list                     
17 list  
```

**7. grep**
it is used to search for a particular information from a textfile
grep[options] pattern [path]

```
root@537302f1e700:~/fruits# grep banana list                 
banana 
```
or 

```
root@537302f1e700:~/fruits# cat list | grep banana           
banana 
```

options
-v it displays names not matching to the specified word
-l it filters output in a case  insensitive way 
-A It displays a line after the result
-B  it displays line before the results
-c  it displays a line before and after the result

**8. nl** nl command is used to number the lines of the text data
  nl [option] [path]
  

```
root@537302f1e700:~/fruits# nl list                          
     1  apple                                                
     2  mango                                                
     3  banana  
```
**9. tr** 
tr command is used for translating or deleting characters
some of its uses include:

to convert lower case to upper case in a file
  cat filename | tr "[a-z]" "[A-Z]" 

```
root@537302f1e700:~/fruits# cat weekdays                     
monday                                                       
applel                                                       
mangoe                                                       
banana                                                       
kibet                                                        
                                                             
root@537302f1e700:~/fruits# cat weekdays  | tr  "[a-z]" "[A-Z
MONDAY                                                       
APPLEL                                                       
MANGOE                                                       
BANANA                                                       
KIBET 
```
**Another** option for this is to use
cat filename  | tr  "[:lower:]"  "[:upper:]"


**-s** used to squeeze repeat occurrence of characters specified in a set
**-d**  it is used to delete a specific character
i.e cat filename | tr -d 'a'      this will delete the letter a in the files content.

```
root@537302f1e700:~/fruits# cat weekdays                     
monday                                                       
applel                                                       
mangoe                                                       
banana                                                       
kibet                                                        
                                                             
root@537302f1e700:~/fruits# cat weekdays | tr -d 'a'         
mondy                                                        
pplel                                                        
mngoe 
```

## **BASH SHELL EXPANSION**
with this the shell expands the "*"  into something else before the echo command is executed
expansion is performed on the command line after it has been  split into tokens
i.e echo this is my  output 
    echo *

```
root@537302f1e700:~/fruits# echo "finding the expansion"     
finding the expansion                                        
root@537302f1e700:~/fruits# echo *                           
apple Apple banana Banana cherry Cherry day days list listing
s melon Melon orange Orange pear Pear weekdays               
root@537302f1e700:~/fruits#                                  
                                
```

**pathname expansion**
This is the mechanism by which wildcards work 
i.e
echo d*  : with this it will print out files starting with the letter d.
echo *a  : with this it will print out files ending with the letter a.

```
root@537302f1e700:~/fruits# echo d*                          
day days                                                     
root@537302f1e700:~/fruits# echo *a                          
banana Banana                                                
root@537302f1e700:~/fruits#                                  
                             
```
 
**Arithmetic expansion**
The expansion allows one to use the shell prompt as a calculator.  
it only supports integers ( only whole numbers)
$((expression))
i.e. echo $((2+2))

```
root@537302f1e700:~/fruits# echo $((2+2))                    
4    
```
 echo $(((5**2) *3))

```
root@537302f1e700:~/fruits# echo $(((5**2) *3))              
75 
```

**Brace Expansion**
With brace expansion, one can be able to create multiple texts strings from a pattern containing braces
i.e echo front- {A,B,C}-Back

```
root@537302f1e700:~/fruits# echo front-{A,B,C}-Back          
front-A-Back front-B-Back front-C-Back 
```
echo number_{1..5} 

```
root@537302f1e700:~/fruits# echo number_{1..5}               
number_1 number_2 number_3 number_4 number_5  
```
 
**Parameter expansion**
Its a feature that is more useful in shell scripts than directly on the command line
i.e print current working directory using a parameter
   echo $PWD

```
root@537302f1e700:~/fruits# echo $PWD                        
/root/fruits
```

**escaping characters ** 
Sometimes we only want to quote a single character  and to do this we can precede a character with a backslash
i.e echo " My bank  balance  bank is : $500

```
root@537302f1e700:~/fruits# echo " my bank balance is: $500" 
 my bank balance is: 00                                      
root@537302f1e700:~/fruits# echo " my bank balance is: \$500"
 my bank balance is: $500  
```










**CONCLUSION**
As we have seen, shell I/O redirection is a powerful feature that allows us to control the input and output of our commands. The shell filters are another powerful tool that can be used to modify the output of our commands. Finally, shell expansion allows us to perform operations on variables and files.

```
Thank you for you time to go through this article, i will appreciate your feedback
Wishing you a Happy Learning
```