linux下的標準輸入、輸出、重定向、管道
在Linux系統(tǒng)中,有4個特殊的符號,<, ‘>’, ‘|’, ‘-‘,在我們處理輸入和輸出時存在重要但具有迷惑性的作用。
默認Linux的命令的結果都是輸出到標準輸出,錯誤信息 (比如命令未找到或文件格式識別錯誤等) 輸出到標準錯誤,而標準輸出和標準錯誤默認都會顯示到屏幕上。
>表示重定向標準輸出,> filename就是把標準輸出存儲到文件filename里面。標準錯誤還是會顯示在屏幕上。
2 >&1 表示把標準錯誤重定向到標準輸出。Linux終端用2表示標準錯誤,1表示標準輸出。
- (短橫線):表示標準輸入,一般用于1個程序需要多個輸入的時候。
<標準輸入,后面可以跟可以產(chǎn)生輸出的命令,一般用于1個程序需要多個輸入的時候。
|管道符,表示把前一個命令的輸出作為后一個命令的輸入,前面也有一些展示例子。用于數(shù)據(jù)在不同的命令之間傳輸,用途是減少硬盤存取損耗。
下面我們通過一個程序stdout_error.sh來解釋上面的文字,內(nèi)容如下
#!/bin/bash
echo "I am std output"
# 下面是隨便寫的一個理論上不存在的命令, 理論上會報錯的。
unexisted_command
運行這個腳本
# 標準輸出和標準錯誤默認都會顯示到屏幕上
ct@ehbio:~$ bash stdout_error.sh
I am std output
stdout_error.sh: line 5: unexisted_command: command not found
# >把結果輸入到了文件;標準錯誤還顯示在屏幕上
ct@ehbio:~$ bash stdout_error.sh >stdout_error.stdout
stdout_error.sh: line 5: unexisted_command: command not found
ct@ehbio:~$ cat stdout_error.stdout
I am std output
# >把結果輸入到了文件; 2>把標準錯誤輸入到了另一個文件
ct@ehbio:~$ bash stdout_error.sh >stdout_error.stdout 2>stdout_error.stderr
ct@ehbio:~$ cat stdout_error.stderr
stdout_error.sh: line 5: unexisted_command: command not found
# 標準輸出和標準錯誤寫入同一個文件
ct@ehbio:~$ bash stdout_error.sh >stdout_error.stdout 2>&1
ct@ehbio:~$ cat stdout_error.stdout
I am std output
stdout_error.sh: line 5: unexisted_command: command not found
下面看管道符和標準輸入的使用。
# 管道符的使用
# 第一個命令的輸出作為第二個的輸入
# 前面的例子中也有使用
# tr: 是用于替換字符的,把空格替換為換行,文字就從一行變?yōu)榱艘涣?ct@ehbio:~$ echo "1 2 3" | tr ' ' 'n'
1
2
3
# cat命令之前也用過,輸出一段文字
# diff是比較2個文件的差異的,需要2個參數(shù)
# - (短橫線)表示上一個命令的輸出,傳遞給diff
# < 表示其后的命令的輸出,也重定向給diff
ct@ehbio:~$ cat <<END | diff - <(echo "1 2 3" | tr ' ' 'n')
> 2
> 3
> 4
> END
0a1
> 1
3d3
< 4
# 如果不使用管道和重定向標準輸入,程序是這么寫的
# 先把第一部分存儲為1個文件
ct@ehbio:~$ cat <<END >firstfile
2
3
> 4
> END
ct@ehbio:~$ less firstfile
# 再把第二部分存儲為1個文件
ct@ehbio:~$ echo "1 2 3" | tr ' ' 'n' >secondfile
# 然后比較
ct@ehbio:~$ diff firstfile secondfile
0a1
> 1
3d3
< 4
管道符的更多應用
ct@ehbio:~$ echo "actg aaaaa cccccg" | tr ' ' 'n' | wc -l
3
# sed =:先輸出行號,再輸出每行的內(nèi)容
ct@ehbio:~$ echo "a b c" | tr ' ' 'n' | sed =
1
a
2
b
3
c
# 后面這個命令不太好解釋
# sed = 同時輸出行號
# N: 表示讀入下一行;sed命令每次只讀一行,加上N之后就是緩存了第2行,所有的操作都針對第一行;
# s: 替換;把換行符替換為t
ct@ehbio:~$ echo "a b c" | tr ' ' 'n' | sed = | sed 'N;s/n/t/'
1 a
2 b
3 c
# 后面這個命令不太好解釋
# sed = 同時輸出行號
# N: 表示讀入下一行;sed命令每次只讀一行,加上N之后就是緩存了第2行,所有的操作都針對第一行;
# s: 替換;把讀取的奇數(shù)行行首加一個'>'(偶數(shù)行相當于被隱藏了)
ct@ehbio:~$ echo "a b c" | tr ' ' 'n' | sed = | sed 'N;s/^/>/'
>1
a
>2
b
>3
c
# 把多條序列轉成FATSA格式
# sed = 同時輸出行號
# N: 表示讀入下一行;sed命令每次只讀一行,加上N之后就是緩存了第2行,所有的操作都針對第一行;
# s: 替換;把讀取的奇數(shù)行行首加一個'>'(偶數(shù)行相當于被隱藏了)
# 于是FASTA格式序列就出來了
ct@ehbio:~$ echo "actg aaaaa cccccg" | tr ' ' 'n' | sed = | sed 'N;s/^/>/'
>1
actg
>2
aaaaa
>3
cccccg