Bash Redirection and Pipes
Redirection sends output into files, and pipes send the output of one command into another. This is where Bash becomes powerful.
Saving Output to a File
>writes the output to a file and replaces what was there.>>adds the output to the end of the file.
Example
echo "Ali" > names.txt
echo "Ayesha" >> names.txt
echo "Bilal" >> names.txt
cat names.txtAli Ayesha Bilal
Be careful with >: it empties the file before writing. Use >> when you want to keep the old contents.
Reading Input from a File
< gives a file to a command as its input:
Example
printf "Ali\nAyesha\nBilal\n" > names.txt
wc -l < names.txt3
Errors: 2>
Commands have two output streams: normal output (stream 1) and error messages (stream 2). You can redirect them separately.
| Symbol | Meaning |
|---|---|
> file | Normal output into a file |
2> file | Error messages into a file |
&> file | Both into one file |
2> /dev/null | Throw error messages away |
Example
ls missing-folder 2> errors.txt
ls missing-folder 2> /dev/null
echo "Done"Done
/dev/null is a special file that throws away everything written to it.
Pipes
The pipe symbol | sends the output of the command on its left into the command on its right. You can join many commands this way.
Example
printf "mango\napple\nbanana\napple\nmango\napple\n" > fruits.txt
sort fruits.txt | uniq
echo "---"
sort fruits.txt | uniq -c | sort -rn | head -n 1apple
banana
mango
---
3 appleRead the second line from left to right: sort the fruits, count each unique one, sort by the count from high to low, and show the top line.
Useful Text Tools
These tools are most useful with pipes:
| Tool | What it does |
|---|---|
grep word | Keeps only lines that contain the word |
sort | Sorts lines (-n for numbers, -r to reverse) |
uniq | Removes repeated lines next to each other (-c counts them) |
wc -l | Counts lines |
head / tail | First or last lines |
cut -d, -f1 | Takes column 1 of comma-separated text |
tr a-z A-Z | Changes characters, here to capital letters |
grep
grep searches text. Add -i to ignore case and -c to count matching lines.
Example
printf "Ali,Karachi,85\nSara,Lahore,92\nHamza,Karachi,78\n" > students.csv
grep "Karachi" students.csv
grep -c "Karachi" students.csv
grep "Karachi" students.csv | cut -d, -f1
cut -d, -f2 students.csv | sort | uniqAli,Karachi,85 Hamza,Karachi,78 2 Ali Hamza Karachi Lahore
Joining Commands
Besides pipes, Bash has other ways to join commands on one line:
a ; brunsa, thenb, alwaysa && brunsbonly ifasucceededa || brunsbonly ifafailed
Example
mkdir -p reports && echo "Folder ready"
ls no-such-file 2> /dev/null || echo "File not found"Folder ready File not found
Exercise
Exercise
What does echo "hi" >> log.txt do?
