Linux學習教程

歡迎關注天下博客:http://blog.genesino.com/2017/06/bash1/
Jump to...

  1. 本教程宗旨 (請仔細閱讀)
  2. 為什么要用Linux系統
  3. 如何獲取Linux系統
  4. 初識Linux系統
  5. 我的電腦在哪?
  6. 獲取可用命令行參數
  7. 文件上下翻轉和左右翻轉
  8. 其它新建文件的方式
  9. Linux下文件操作
  10. Linux下命令的一些異常情況
  11. Linux下文件內容操作
  12. Linux終端常用快捷操作
  13. Linux下的標準輸入、輸出、重定向、管道
  14. 文件的可執行屬性和環境變量
  15. 環境變量的補充
  16. 文件內容操作 (二)
  17. 文件排序
  18. FASTA序列提取
  19. 命令運行監測
  20. 文件系統和磁盤信息監測
  21. 軟件安裝
  22. 系統包管理器安裝
  23. 源碼編譯安裝
  24. Python包的安裝
  25. Anaconda的兩個福利
  26. R包的安裝
  27. 備注
  28. Original link
  29. 微信公眾號

本教程宗旨 (請仔細閱讀)

本教程不是一個完備的Linux使用教程,而是側重于一般教程默認讀者會了的信息,包括基本概念的解釋 (方便初學者了解自己的操作)、命令的各種錯誤及解決 (通常寫教程的都是對這一領域比較熟悉的,一般不會提到這些初學者剛開始不好理解的簡單錯誤)、部分常用命令 (會提到基本用法,具體的使用還請查看手冊或在線搜索)、常用快捷鍵 (簡化操作)和組合命令 (快速的批處理等,初學者一般不會想到、高級學者又不屑于提起的部分)。

為什么要用Linux系統

個人認為,Linux操作系統和類Linux操作系統的命令行界面是最適合進行生物信息分析的操作系統。原因有三點:

  • 長期運行的穩定性
  • 多數軟件只有Linux版本
  • 強大的Bash命令簡化繁瑣的操作,尤其是大大簡化重復性工作

但對于初學者來說,接觸和理解Linux操作系統需要一些時間和摸索。陡然從可視化點選操作的Windows進入到只有命令行界面的Linux,最大的陌生感是不知道做什么,不知道文件在哪?本文希望能通過幾個示例幫助大家適應Linux系統。

如何獲取Linux系統

  • 如果自己的單位有共有服務器,可以嘗試申請賬號。
  • 自己的電腦安裝雙系統或虛擬機
  • 購買一塊云服務器
  • 試驗下在線學習平臺實驗樓 https://www.shiyanlou.com (里面也有不少Linux教程,任意點一個進去,雙擊桌面的Xfce圖標,都可以啟動Linux終端)
  • <生信寶典>微信公眾號后臺回復向管理員索要

初識Linux系統

登錄Linux系統后,呈現在眼前的是這樣一個界面:

Last login: Mon Jun  5 16:56:56 2017 from 219.241.208.209

Welcome to aliyun Elastic Compute Service!

ct@ehbio:~$ 

首先解釋下出現的這幾個字母和符號:

  • ct: 用戶名
  • ehbio:如果是登錄的遠程服務器,則為宿主機的名字
  • ~: 代表家目錄, 在我們進入新的目錄后,這個地方會跟著改變
  • $: 用來指示普通用戶輸入命令的地方;對根用戶來說一般是#
  • http://bashrcgenerator.com/可視化定制不同的顯示方式。

我的電腦在哪?

打開Windows,首先看到的是桌面;不愛整理文件的我,桌面的東西已經多到需要2個屏幕才能顯示的完。另外一個常用的就是我的電腦,然后打開D盤,依次點開對應的文件夾,然后點開文件。

Linux的文件系統組織方式與Windows略有不同,登錄進去就是家目錄,可視為Windows下的桌面。在這個目錄下,我們可以新建文件、新建文件夾,就像在桌面上的操作一樣。

注:

  • 這里我們假設所有用到的文件和文件夾都放置于家目錄下
  • Linux的家目錄嚴格來說可能類似于Windows下的C:\Users\ct

如果想查看當前目錄下都有什么內容,輸入命令 ls,回車即可 (ls可以理解為單詞list的縮寫)。當前目錄下什么也沒有,所以沒有任何輸出。

ct@ehbio:~$ ls

如果錯把l看成了i,輸入了is,則會出現下面的提示未找到命令。如果輸入的是Linux基本命令,出現這個提示,基本可以判定是命令輸入錯了,瞪大眼睛仔細看就是了。 在敲完命令回車后,注意查看終端的輸出,以判斷是否有問題。

ct@ehbio:~$ is
-bash: is: 未找到命令
# 大小寫敏感
ct@ehbio:~$ lS
-bash: lS: 未找到命令

當前目錄下只有一個文件,看不出效果,我們可以新建幾個文件和文件夾,來查看下。

mkdir是新建一個目錄 (make a directory);data是目錄的名字。 如果目錄存在,則會出現提示,”無法創建已存在的目錄”。這時可以使用參數-p忽略這個錯誤。

ct@ehbio:~$ mkdir data
ct@ehbio:~$ mkdir ls
data
ct@ehbio:~$ mkdir data
mkdir: 無法創建目錄"data" : 文件已存在
ct@ehbio:~$ mkdir -p data

cat是一個命令,主要用來查看文件;在這與<<END連用用于讀入大段數據。輸入cat <<END之后,回車,會看到終端出現一個大于號,大于號后面可以輸入內容,再回車,繼續輸入內容,直到我們輸入END (大寫的,與上面一致),輸入過程結束,我們輸入的內容都顯示在了屏幕上。

ct@ehbio:~$ mkdir data
ct@ehbio:~$ cat <<END
> a
> bc
> END
a
bc

`>`是一個重定向符號,即把前面命令的輸出寫入到`>`后面的文件中。如下所示,新建了一個`Fasta`格式的文件。
`ls -l`列出文件的詳細信息;`-l`表示命令行參數,是程序預留的一些選項,保證在不更改程序的情況下獲得更靈活的操作。可使用`man ls`查看`ls`所有的命令行參數, 上下箭頭翻頁,按`q`退出查看。(man: manual, 手冊)

```bash
ct@ehbio:~$ cat <<END >data/test.fa
> >SOX2
> ACGTCGGCGGAGGGTGGSCGGGGGGGGAGAGGT
> ACGATGAGGAGTAGGAGAGAGGAGG
> >OCT4
> ACGTAGGATGGAGGAGAGGGAGGGGGGAGGAGAGGAA
> AGAGTAGAGAGA
> >NANOG
> ACGATGCGATGCAGCGTTTTTTTTTGGTTGGATCT
> CAGGTAGGAGCGAGGAGGCAGCGGCGGATGCAGGCA
> ACGGTAGCGAGTC
> >mYC HAHA
> ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
> CAGGACAGGAGCTA
> end
> END
## 注意命令和參數之間的空格
ct@ehbio:~/data$ ls-l
-bash: ls-l: 未找到命令
ct@ehbio:~$ ls -l
總用量 4
## d: dir; 表示data是個目錄
## rwx:表示目錄的權限,暫時忽略,或自己在線搜索
drwxrwxr-x 2 ct ct 4096 6月   8 14:52 data
ct@ehbio:~$ ls -l data
總用量 4
## 開頭的`-`表示test.fa是個文件
-rw-rw-r-- 1 ct ct 284 6月   8 14:48 test.fa

查看寫入的文件的內容,cat 文件名;需要注意的是文件所在的目錄,默認是當前目錄;如下面第一個命令,會提示cat: test.fa: 沒有那個文件或目錄,是因為當前目錄下不存在文件test.fa。(注意文件末尾的end)

ct@ehbio:~$ cat test.fa
cat: test.fa: 沒有那個文件或目錄
ct@ehbio:~$ cat data/test.fa 
>SOX2
ACGTCGGCGGAGGGTGGSCGGGGGGGGAGAGGT
ACGATGAGGAGTAGGAGAGAGGAGG
>OCT4
ACGTAGGATGGAGGAGAGGGAGGGGGGAGGAGAGGAA
AGAGTAGAGAGA
>NANOG
ACGATGCGATGCAGCGTTTTTTTTTGGTTGGATCT
CAGGTAGGAGCGAGGAGGCAGCGGCGGATGCAGGCA
ACGGTAGCGAGTC
>mYC HAHA
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end

test.fa在目錄data下,可以先進入data目錄,然后再查看文件。類比于Windows下先點開一個文件夾,再點開下面的文件。

cd (change dir)切換目錄。

head查看文件最開始的幾行,默認為10行,可使用-n 6指定查看前6行。

ct@ehbio:~$ cd data
ct@ehbio:~/data$ head -n 6 test.fa 
>SOX2
ACGTCGGCGGAGGGTGGSCGGGGGGGGAGAGGT
ACGATGAGGAGTAGGAGAGAGGAGG
>OCT4
ACGTAGGATGGAGGAGAGGGAGGGGGGAGGAGAGGAA
AGAGTAGAGAGA

另外lessmore也可以用來查看文件,尤其是文件內容特別多的時候。

ct@ehbio:~/data$ less test.fa 
# q: 退出
# 上下箭頭、空格翻頁

獲取可用命令行參數

前面使用的命令,有幾個用到了參數如ls -l, head -n 6等,需要注意的是命令跟參數之間要有空格

終端運行man ls可以查看ls所有可用的參數,上下箭頭翻頁,按q退出查看。(man: manual, 手冊)

ct@ehbio:~/data$ man ls
NAME
 ls - list directory contents

SYNOPSIS
 ls [OPTION]... [FILE]...

DESCRIPTION
 List  information  about  the  FILEs  (the current directory by default).
 Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.

 Mandatory arguments to long options are mandatory for short options too.

 -a, --all
  do not ignore entries starting with .

 -A, --almost-all
  do not list implied . and ..

 --author
  with -l, print the author of each file

 -b, --escape
  print C-style escapes for nongraphic characters
 ....

文件上下翻轉和左右翻轉

兩個有意思的命令,tac: 文件翻轉,第一行變為最后一行,第二行變為倒數第二行;rev每列反轉,第一個字符變為最后一個字符,第二個字符變為倒數第二個字符。

ct@ehbio:~/data$ cat <<END | tac
> first
> second
> third
> END
third
second
first
ct@ehbio:~/data$ cat <<END | rev
> abcde
> xyz
> END
edcba
zyx

其它新建文件的方式

nano類似于Windows下記事本的功能,nano filename就可以新建一個文件,并在里面寫內容;ctrl+x退出,根據提示按Y保存。

vim 功能更強大的文本編輯器。vim filename就可以新建一個文件, 敲擊鍵盤字母i,進入寫作模式。寫完后,敲擊鍵盤Esc, 退出寫作模式,然后輸入:w (會顯示在屏幕左下角),回車保存。vim的常用方法,以后會單寫一個,這里點到為止。

Linux下文件操作

常用的文件操作有移動文件到另一個文件夾、復制文件到另一個文件夾、文件重命名等。

cp (copy): 拷貝文件或文件夾 (cp -r 拷貝文件夾時的參數,遞歸拷貝)

# 列出當前目錄下有的文件和文件夾
ct@ehbio:~$ ls
data

# 新建一個文件夾
ct@ehbio:~$ mkdir ehbio_project

# 列出當前目錄下有的文件和文件夾, 及其子文件夾的內容
# data目錄下有一個文件,ehbio_project目錄下無文件
ct@ehbio:~$ ls *
data:
test.fa

ehbio_project:

# 拷貝data目錄下的文件test.fa到ehbio_project目錄下
ct@ehbio:~$ cp data/test.fa ehbio_project/

# 列出當前目錄下有的文件和文件夾, 及其子文件夾的內容
# data目錄下有一個文件,ehbio_project目錄下無文件
ct@ehbio:~$ ls *
data:
test.fa

ehbio_project:
test.fa

mv (move): 移動文件或文件夾

# 重命名data目錄下的文件test.fa為first.fa
# mv除了可以移動文件,也可以做單個文件的重命名
ct@ehbio:~$ mv data/test.fa data/first.fa

# 列出當前目錄下有的文件和文件夾,  及其子文件夾的內容
ct@ehbio:~$ ls *
data:
first.fa

ehbio_project:
test.fa

rename: 文件重命名 (常用于批量重命名,不同的系統可能用法略有不同,使用前先man rename查看使用方法)

# 進入另一個目錄
ct@ehbio:~$ cd ehbio_project/
ct@ehbio:~/ehbio_project$ ls
test.fa

# 給文件做一份拷貝
ct@ehbio:~/ehbio_project$ cp test.fa second.fa
ct@ehbio:~/ehbio_project$ ls
second.fa  test.fa

# 給文件多拷貝幾次,無聊的操作,就是為了給rename提供發揮作用的機會
ct@ehbio:~/ehbio_project$ cp test.fa test2.fa
ct@ehbio:~/ehbio_project$ cp test.fa test3.fa
ct@ehbio:~/ehbio_project$ cp test.fa test4.fa

# cp 后面需要2個參數,被拷貝的文件和要被拷貝到的目錄或文件
# 出現下面的錯誤,表示缺少目標路徑或文件
ct@ehbio:~/ehbio_project$ cp ehbio.fa 
cp: 在" ehbio.fa"  后缺少了要操作的目標文件
Try 'cp --help' for more information.

ct@ehbio:~/ehbio_project$ ls
second.fa  test2.fa  test3.fa  test4.fa  test.fa

# 用rename進行文件批量重命名
ct@ehbio:~/ehbio_project$ rename 'test' 'ehbio' test*.fa
ct@ehbio:~/ehbio_project$ ls
ehbio2.fa  ehbio3.fa  ehbio4.fa  ehbio.fa  second.fa

ln (link): 給文件建立快捷方式 (ln -s source_file target 創建軟連接)。

在建立軟連接時,原文件要使用全路徑。全路徑指以/開頭的路徑。

建立軟連接,是為了在不增加硬盤存儲的情況下,簡化文件訪問方式的一個辦法。把其它文件夾下的文件鏈接到當前目錄,使用時只需要寫文件的名字就可以了,不需要再寫長串的目錄了。

../: 表示上一層目錄;../../: 表示上面兩層目錄

pwd (print current/working directory): 輸出當前所在的目錄

\``為鍵盤Esc下第一個按鍵 (與家目錄~`符號同一個鍵),寫在反引號內的命令會被運行,運行結果會放置在反引號所在的位置

# 建立軟連接,把當前目錄下的ehbio2.fa,鏈接到上一層目錄的data下面

# 這是一個無效的軟連接,
ct@ehbio:~/ehbio_project$ ln -s ehbio2.fa ../data

# 在使用ls查看時,無效的軟連接的文件名下面是黑色的背景。
ct@ehbio:~/ehbio_project$ ls -l ../data/
總用量 4
lrwxrwxrwx 1 ct ct   9 6月   9 17:55 ehbio2.fa -> ehbio2.fa
-rw-rw-r-- 1 ct ct 284 6月   8 14:48 first.fa

# 輸出當前所在的目錄
ct@ehbio:~/ehbio_project$ pwd
/home/ct/ehbio_project

# 建立軟連接時,原始文件一定使用全路徑。全路徑指以/開頭的路徑。
ct@ehbio:~/ehbio_project$ ln -s /home/ct/ehbio_project/ehbio2.fa ../data
ln: 無法創建符號鏈接" ../data/ehbio2.fa" : 文件已存在

# 上面的錯誤信息時,已經存在這么一個鏈接了(雖然是無效的),但再建新的鏈接時還會提示
# 使用`-f` (force)強制覆蓋已有的鏈接
ct@ehbio:~/ehbio_project$ ln -fs `pwd`/ehbio2.fa ../data

# 再次查看時,就正常了。文件名下面沒有了背景色,并且有個右箭頭指向原始文件
# `lrwxrwxrwx`中的`l`表示軟連接。
ct@ehbio:~/ehbio_project$ ls -l ../data/
總用量 4
lrwxrwxrwx 1 ct ct  32 6月   9 17:56 ehbio2.fa -> /home/ct/ehbio_project/ehbio2.fa
-rw-rw-r-- 1 ct ct 284 6月   8 14:48 first.fa

# 通常為了簡化寫法,使用`pwd`代替全路徑
# `為鍵盤Esc下面的按鍵,寫在反引號內的命令會被運行,運行結果會放置在反引號所在的位置
ct@ehbio:~/ehbio_project$ ln -s `pwd`/ehbio2.fa ../data
ln: 無法創建符號鏈接" ../data/ehbio2.fa" : 文件已存在
ct@ehbio:~/ehbio_project$ ln -fs `pwd`/ehbio2.fa ../data
ct@ehbio:~/ehbio_project$ ls -l ../data/
總用量 4
lrwxrwxrwx 1 ct ct  32 6月   9 17:56 ehbio2.fa -> /home/ct/ehbio_project/ehbio2.fa
-rw-rw-r-- 1 ct ct 284 6月   8 14:48 first.fa

Linux下命令的一些異常情況

命令不全:在命令沒有輸入完 (引號或括號沒有配對),就不小心按下了Enter鍵,終端會提示出一個>代表命令不完整,這是可以繼續輸入,也可以ctrl+c終止輸入,重新再來。(下面sed命令使用時,還有另外一種命令不全的問題)

ct@ehbio:~/ehbio_project$ rename 'ehbio2
>'
ct@ehbio:~/ehbio_project$ rename 'ehbio2
> ^C
ct@ehbio:~/ehbio_project$

文件名輸入錯誤: 多一個字母、少一個字母、大小寫問題

ct@ehbio:~/ehbio_project$ls
ehbio2.fa  ehbio3.fa  ehbio4.fa  ehbio.fa  second.fa

# 重命名沒有生效
ct@ehbio:~/ehbio_project$ rename 'ehbio2' 'ehbio5' ebio2.fa
ct@ehbio:~/ehbio_project$ ls
ehbio2.fa  ehbio3.fa  ehbio4.fa  ehbio.fa  second.fa

# 仔細看是ehbio2.fa寫成了ebio2.fa,更正后即可。
Z8vb3e9jtel4m99ss6e7eZ:~/ehbio_project$ rename 'ehbio2' 'ehbio5' ehbio2.fa
ct@ehbio:~/ehbio_project$ ls
ehbio3.fa  ehbio4.fa  ehbio5.fa  ehbio.fa  second.fa

所在目錄不對: 訪問的文件不存在于當前目錄,而又沒有提供絕對路徑, 或軟連接失效

ct@ehbio:~/ehbio_project$ ls
ehbio3.fa  ehbio4.fa  ehbio5.fa  ehbio6.fa  ehbio.fa  second.fa
ct@ehbio:~/ehbio_project$ ls ../data
ehbio2.fa  first.fa

# 當前目錄沒有ehbio2.fa
ct@ehbio:~/ehbio_project$ less ehbio2.fa
ehbio2.fa: 沒有那個文件或目錄

# ehbio2.fa在上一層目錄的data目錄下
ct@ehbio:~/ehbio_project$ ls ../data/ehbio2.fa 
../data/ehbio2.fa

# 加上路徑依然訪問不了 
ct@ehbio:~/ehbio_project$ less ../data/ehbio2.fa 
../data/ehbio2.fa: 沒有那個文件或目錄

# 上面的問題是軟連接失效,在之前的操作中刪掉了原始的ehbio2.fa,所以快捷方式失效

# 正確的訪問
ct@ehbio:~/ehbio_project$ tail -n 3 ../data/first.fa 
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end

Linux下文件內容操作

常用的文件內容操作有文件壓縮解壓縮、文件大小行數統計、文件內容查詢等。

gzip: 壓縮文件; gunzip: 解壓縮文件

# gzip -c 把壓縮的文件輸出到標準輸出 (一般是屏幕)
# '>' 輸出重定向,輸出寫入文件

ct@ehbio:~/ehbio_project$ gzip -c ehbio.fa >ehbio.fa.gz

# 多了一個.gz文件
ct@ehbio:~/ehbio_project$ ls
ehbio3.fa  ehbio4.fa  ehbio5.fa  ehbio.fa  ehbio.fa.gz  second.fa

#解壓縮
ct@ehbio:~/ehbio_project$ gunzip ehbio.fa.gz
gzip: ehbio.fa already exists; do you wish to overwrite (y or n)? y
ct@ehbio:~/ehbio_project$ ls
ehbio3.fa  ehbio4.fa  ehbio5.fa  ehbio.fa  second.fa

wc (word count): 一般使用wc -l獲取文件的行數

# 輸出文件有14行
ct@ehbio:~/ehbio_project$ wc -l ehbio.fa
14 ehbio.fa

獲取文件中包含大于號 (>)的行, grep (print lines matching a pattern)。 grep的用法很多,支持正則表達式匹配,這里不展開,可以自己查閱資料,或在后期的教程涉及到時再學習。

ct@ehbio:~/ehbio_project$ grep '>' ehbio.fa
>SOX2
>OCT4
>NANOG
>mYC HAHA

# 獲取包含>的行的行數 (-c: count lines)
ct@ehbio:~/ehbio_project$ grep -c '>' ehbio.fa
4

# 是不是還記得當時新建文件時,末尾多了一行end,刪除end所在行
ct@ehbio:~/ehbio_project$ less ehbio.fa 

# -v: 不輸出匹配上的行
ct@ehbio:~/ehbio_project$ grep -v 'end' ehbio.fa >ehbio6.fa
ct@ehbio:~/ehbio_project$ cat ehbio6.fa 
>SOX2
ACGTCGGCGGAGGGTGGSCGGGGGGGGAGAGGT
ACGATGAGGAGTAGGAGAGAGGAGG
>OCT4
ACGTAGGATGGAGGAGAGGGAGGGGGGAGGAGAGGAA
AGAGTAGAGAGA
>NANOG
ACGATGCGATGCAGCGTTTTTTTTTGGTTGGATCT
CAGGTAGGAGCGAGGAGGCAGCGGCGGATGCAGGCA
ACGGTAGCGAGTC
>mYC HAHA
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA

替換文件中的字符: sed是一個功能強大的文件內容編輯工具,常用于替換、取得行號等操作。

# 第一個錯誤,漏掉了文件名
# 程序靜止在這,等待用戶的進一步輸入
# ctrl+c殺掉當前命令
ct@ehbio:~/ehbio_project$ sed 's/ HAHA//' | tail -n 3

^C

# 第二個錯誤,文件名和單引號之間沒有空格,使得sed判斷命令錯誤

ct@ehbio:~/ehbio_project$ sed 's/ HAHA//'ehbio.fa  | tail -n 3
sed:-e 表達式 #1,字符 11:“s”的未知選項

# 正確操作,

ct@ehbio:~/ehbio_project$ sed 's/ HAHA//' ehbio.fa  | tail -n 4
>mYC
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end

另外一個方式,去除HAHA,使用cut命令 (cut更適合與矩陣操作,去除其中的一列或者多列)。

-f: 指定取出哪一列,使用方法為-f 2 (取出第2列),-f 2-5 (取出第2-5列),-f 2,5 (取出第2和第5列)。

-d: 設定分隔符, 默認為TAB鍵。如果一行沒有指定的分隔符,整行都為第一列。

ct@ehbio:~/ehbio_project$ cut -f 1 -d ' ' ehbio.fa | tail -n 4
>mYC
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end

Linux終端常用快捷操作

  • 命令或文件名自動補全:在輸入命令或文件名的前幾個字母后,按Tab鍵,系統會自動補全或提示補全
  • 上下箭頭:使用上下箭頭可以回溯之前的命令,增加命令的重用,減少輸入工作量
  • !加之前輸入過的命令的前幾個字母,快速獲取前面的命令
ct@ehbio:~/ehbio_project$ cut -f 1 -d ' ' ehbio.fa | tail -n 4
>mYC
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end
ct@ehbio:~/ehbio_project$ man cut
# 直接跳到上面運行的cut命令,再執行一次
ct@ehbio:~/ehbio_project$ !cut
cut -f 1 -d ' ' ehbio.fa | tail -n 4
>mYC
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end

  • ctrl+a回到命令的行首,用于修改常命令或注釋掉命令
# 寫完下面的命令,突然不想運行了,又不想一個個刪掉
ct@ehbio:~/ehbio_project$ cut -f 1 -d ' ' ehbio.fa | tail -n 4

# 按ctrl+a, 回到行首,再輸入`#`號,回車,命令即被注釋掉。
ct@ehbio:~/ehbio_project$ #cut -f 1 -d ' ' ehbio.fa | tail -n 4

  • !! 表示上一條命令。
ct@ehbio:~/ehbio_project$ ls
ehbio3.fa  ehbio4.fa  ehbio5.fa  ehbio6.fa  ehbio.fa  second.fa
ct@ehbio:~/ehbio_project$ !!
ls
ehbio3.fa  ehbio4.fa  ehbio5.fa  ehbio6.fa  ehbio.fa  second.fa

  • 替換上一個命令中的字符,再運行一遍命令,用于需要對多個文件執行同樣的命令,又不想寫循環的情況
# 輸入一個命令
ct@ehbio:~/ehbio_project$ #cut -f 1 -d ' ' ehbio.fa | tail -n 4

# !!表示上一條命令
# :gs表示替換,把上一個命令中全部的ehbio替換為ehbio3; g: global; s: substitute
ct@ehbio:~/ehbio_project$ !!:gs/ehbio/ehbio3
#cut -f 1 -d ' ' ehbio3.fa | tail -n 4

# 替換后效果如上

# 去掉命令前的#號
ct@ehbio:~/ehbio_project$ cut -f 1 -d ' ' ehbio3.fa | tail -n 4
>mYC
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end

## 替換ehbio3為ehbio4,直接運行命令
ct@ehbio:~/ehbio_project$ !!:gs/ehbio3/ehbio4
cut -f 1 -d ' ' ehbio4.fa | tail -n 4
>mYC
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end

Linux下的標準輸入、輸出、重定向、管道

| 在Linux系統中,有4個特殊的符號,<, ‘>’, ‘ | ’, ‘-‘,在我們處理輸入和輸出時存在重要但具有迷惑性的作用。 |

默認Linux的命令的結果都是輸出到標準輸出,錯誤信息 (比如命令未找到或文件格式識別錯誤等) 輸出到標準錯誤,而標準輸出和標準錯誤默認都會顯示到屏幕上。

>表示重定向標準輸出,> filename就是把標準輸出存儲到文件filename里面。標準錯誤還是會顯示在屏幕上。

2 >&1 表示把標準錯誤重定向到標準輸出。Linux終端用2表示標準錯誤,1表示標準輸出。

- (短橫線):表示標準輸入,一般用于1個程序需要多個輸入的時候。

<標準輸入,后面可以跟可以產生輸出的命令,一般用于1個程序需要多個輸入的時候。

|管道符,表示把前一個命令的輸出作為后一個命令的輸入,前面也有一些展示例子。用于數據在不同的命令之間傳輸,用途是減少硬盤存取損耗。

下面我們通過一個程序stdout_error.sh來解釋上面的文字,內容如下

#!/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: 是用于替換字符的,把空格替換為換行,文字就從一行變為了一列
ct@ehbio:~$ echo "1 2 3" | tr ' ' '\n'
1
2
3

# cat命令之前也用過,輸出一段文字
# diff是比較2個文件的差異的,需要2個參數
# - (短橫線)表示上一個命令的輸出,傳遞給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 =:先輸出行號,再輸出每行的內容
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: 替換;把讀取的奇數行行首加一個'>'(偶數行相當于被隱藏了)
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: 替換;把讀取的奇數行行首加一個'>'(偶數行相當于被隱藏了)
# 于是FASTA格式序列就出來了
ct@ehbio:~$ echo  "actg aaaaa cccccg" | tr ' ' '\n' | sed = | sed 'N;s/^/>/' 
>1
actg
>2
aaaaa
>3
cccccg

文件的可執行屬性和環境變量

Linux下文件有一個特殊的屬性即可執行屬性,用來指示這個文件是一個可執行的腳本或可以運行的二進制文件。前面所提到的這些命令,都具有可執行屬性。

which: 表示查看命令的路徑。一般用于當我們想知道使用的命令來源于什么地方時,比如安裝了多個R或多個python,但又分不清用的是哪個時,which一下,立即明了。在這兒我們用which獲取的是可執行的命令所在的路徑,進而查看其屬性。

ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l "`which cd`"
#rwx: 文件所有者可讀、可寫、可執行
#r-x: 文件所有者所在組其它成員可讀、可執行,不可修改
#r-x: 其它人可讀、可執行,不可修改
-rwxr-xr-x 1 root root 26 12月  7 2016 /usr/bin/cd
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l "`which mkdir`"
-rwxr-xr-x. 1 root root 79768 11月  6 2016 /usr/bin/mkdir
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l "`which python`"
#l: 代表軟連接
#軟連接自身是所有人可讀可寫,但具體的權限依賴于其鏈接的文件
lrwxrwxrwx. 1 root root 7 3月  22 15:04 /usr/bin/python -> python2
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l "`which python2`"
#第二層鏈接
lrwxrwxrwx. 1 root root 9 3月  22 15:04 /usr/bin/python2 -> python2.7
#鏈接的原始文件
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l "`which python2.7`"
-rwxr-xr-x. 1 root root 7136 11月  6 2016 /usr/bin/python2.7

文件屬性rwxr表示read (數字表示為4)、w表示write (數字表示為2)、x表示執行 (數字表示為1)。三個未一組,連續出現三次(如下面命令行中所示), 第一組表示文件的所有者擁有的權限,第二組為文件所有者所在的用戶組所擁有的權限,組內所有成員都具有的權限,第三組為其它用戶的權限。

chmod a+x file: 表示給文件增加所有人(a)可執行權限 (+x)

chmod u+x file: 表示給文件增加所有者(u,user,)可執行權限 (+x)

chmod g+x, chmod o+X: 表示給文件增加組內人或其它人可執行權限

chmod 755 file: 表示擁有者有可讀寫執行權限,其它人有可讀執行權限。(7=4+2+1; 5=4+1)

具體使用man chmod查看其它參數使用。

# 新建個文件
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ cat <<END >run.sh
> echo " I am a script created by ehbio." 
> END

# 查看其權限值
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l run.sh 
-rw-rw-r-- 1 ct ct 39 6月  14 23:12 run.sh

# 更改權限值
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ chmod 755 run.sh

# 查看其權限值
# 注意多了3個x
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l run.sh 
-rwxr-xr-x 1 ct ct 39 6月  14 23:12 run.sh

# 去除其它用戶的可執行權限
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ chmod o-x run.sh 

# 注意看少了個x
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l run.sh 
-rwxr-xr-- 1 ct ct 39 6月  14 23:12 run.sh

# 去除同組的可執行權限
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ chmod g-x run.sh

# 注意看又少了個x
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l run.sh 
-rwxr--r-- 1 ct ct 39 6月  14 23:12 run.sh

# 去除所有人的可執行權限
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ chmod a-x run.sh
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l run.sh 
-rw-r--r-- 1 ct ct 39 6月  14 23:12 run.sh

# 給所有人增加可執行權限
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ chmod a+x run.sh
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l run.sh 
-rwxr-xr-x 1 ct ct 39 6月  14 23:12 run.sh

如果一個文件有了可執行權限,是不是就可以執行了,我們來檢測下。

ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ run.sh
-bash: run.sh: 未找到命令

事實上并非如此,輸入命令,回車后,提示命令未找打,這是為什么呢?

這就涉及到環境變量的概念,通俗的講,環境變量就是告訴電腦 (實際是操作系統)幾個目錄。這幾個目錄下存儲又可執行文件,如前面顯示的/usr/bin目錄,大部分的系統命令都在這個目錄下。

當我們輸入命令mkdir時,系統就會在環境變量所代表的幾個目錄從前都厚去查找,哪個里面有mkdir文件,然后去執行mkdir命令。

系統中環境變量的名字是PATH,其內容可通過下面的命令顯示 (根據操作系統不同和配置不同,略有差別,但格式是統一的,:分割的一堆路徑):

ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin

所以如果我們想讓自己的命令能被系統找到,就需要把命令所在的目錄加到環境變量里面,怎么操作呢?

加到環境變量的路徑必須是全路徑,全路徑指以/開頭或已~開頭的路徑。

# 加到環境變量的路徑必須是全路徑,全路徑指以/開頭或已~開頭的路徑
# 注意第一個PATH不含$, 第二個PATH有$符號
# 我們后面會講什么時候用$, 什么時候不用$
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ export PATH=$PATH:/home/ct
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ct

這時,我們在執行那個命令試試,成功運行了。

ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ run.sh 
I am a script created by ehbio.

所以在以后安裝了新的軟件,或者寫了新的腳本后,都把軟件的可執行程序可執行的腳本所在的目錄,加到環境變量里面就可以了。

但是,在命令行中執行export,對環境變量所做的修改,只對當前終端有效,退出后就無效了。為了使得這一操作,長期有效,我們需要把這句話寫入一個文件中,一個登陸服務器就會被自動讀取的文件中。

對于普通用戶,在遠程登錄終端時,家目錄下的~/.bash_profile (不是~/.bashrc, 在本地登錄時才會被讀取)會自動被讀取,所以我們需要把export語句加入到這個文件中。

# 這是我的~/.bash_profile中的內容,主要是最好一行。可以連續的加入多個路徑。
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

export PATH=$PATH:/home/ct:/home/bin:/home/soft/bowtie2/bin

前面提到,系統查找命令的順序是從環境變量的第一個目錄到最后一個目錄,在第一次碰到查詢的命令后,就調用執行。假如系統存在一個python命令,我們自己又安裝了一個python (假如在/home/ct/anaconda/bin目錄下),如果我們想執行自己的python程序,就需要把/home/ct/anaconda/bin寫在$PATH前面,如下

# 注意$PATH的順序

ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ export PATH=/home/ct/anaconda/bin:$PATH

至此,我們可以熟練使用環境變量來簡化命令的輸入過程了,因為如果沒有環境變量,我們就得需要運行/home/ct/anaconda/bin/python來運行python命令了。

環境變量這塊,自己多操作下,就會慢慢理解熟練了。

環境變量的補充

PATH只是眾多環境變量中的一個變量,用于存儲可執行文件所在的目錄,以便在用戶輸入命令時可以查詢的到。尤其是自己寫的腳本或安裝的程序,系統不會知道它們在哪個路徑下,需要我們去提供給系統這些新的路徑,學名叫設置環境變量。

此外常用到的環境變量還有LD_LIBARY_PATH: 指定動態鏈接庫 (so文件)的位置,一般在安裝軟件出錯時會用到;PYTHONPATH: 指定Python的安裝包的路徑;PERL5LIB: 指定perl的安裝包的路徑。

設置環境變量要注意2點:1. 設置新的環境變量時一般要包含原始的環境變量,不能覆蓋;2. 注意自己的目錄和系統環境變量的目錄的順序,想讓哪個先被找到,就先放哪個。

文件內容操作 (二)

文件排序

seq: 產生一系列的數字; man seq查看其具體使用。我們這使用seq產生下游分析所用到的輸入文件。

# 產生從1到10的數,步長為1
ct@ehbio:~$ seq 1 10
1
2
3
4
5
6
7
8
9
10

# 產生從1到10的數,步長為1,用空格分割
ct@ehbio:~$ seq -s ' ' 1 10
1 2 3 4 5 6 7 8 9 10

# 產生從1到10的數,步長為2
# 如果有3個數,中間的數為步長,最后一個始終為最大值
ct@ehbio:~$ seq -s ' ' 1 2 10
1 3 5 7 9

# 還記得前面提到的標準輸入和標準輸出吧
# 后臺回復 標準輸入 查看
ct@ehbio:~$ cat <(seq 0 3 17) <(seq 3 6 18) >test
ct@ehbio:~$ cat test 
0
3
6
9
12
15
3
9
15

sort: 排序,默認按字符編碼排序。如果想按數字大小排序,需添加-n參數。

# 可能不符合預期的排序,系統首先排0,然后排1, 3, 6, 9
ct@ehbio:~$ sort test
0
12
15
15
3
3
6
9
9
# 按數字大小排序
ct@ehbio:~$ sort -n test
0
3
3
6
9
9
12
15
15

sort -u: 去除重復的行,等同于sort | uniq

ct@ehbio:~$ sort -nu test
0
3
6
9
12
15

sort file | uniq -d: 獲得重復的行。(d=duplication)

ct@ehbio:~$ sort -n test | uniq -d
3
9
15

sort file | uniq -c: 獲得每行重復的次數。

# 第一列為每行出現的次數,第二列為原始的行
ct@ehbio:~$ sort -n test | uniq -c
  1 0
  2 3
  1 6
  2 9
  1 12
  2 15

# 換一個文件看的更清楚
ct@ehbio:~$ cat <<END >test2
> a
> b
> c
> b
> a
> e
> d
> a
> END

# 第一列為每行出現的次數,第二列為原始的行
ct@ehbio:~$ sort test2 | uniq -c
3 a
2 b
1 c
1 d
1 e

# 在執行uniq操作前,文件要先排序,不然結果很詭異
ct@ehbio:~$ cat test2 | uniq -c
1 a
1 b
1 c
1 b
1 a
1 e
1 d
1 a

整理下uniq -c的結果,使得原始行在前,每行的計數在后。

awk是一個強大的文本處理工具,其處理數據模式為按行處理。每次讀入一行,進行操作。OFS: 輸出文件的列分隔符 (output file column separtor);FS為輸入文件的列分隔符 (默認為空白字符)。awk中的列從第1到n列,分別記錄為$1, $2$nBEGIN表示在文件讀取前先設置基本參數;與之相對應的是END,只文件讀取完成之后進行操作。不以BEGIN, END開頭的{}就是文件讀取、處理的部分。

# 管道符還記得吧,后臺回復 管道 可查看
# awk的操作就是鍍金上一步的結果,去除多余的空白,然后調換2列
ct@ehbio:~$ sort test2 | uniq -c | awk 'BEGIN{OFS="\t";}{print $2, $1}'
a   3
b   2
c   1
d   1
e   1

對兩列文件,安照第二列進行排序, sort -k2,2n

# 第二列按數值大小排序
ct@ehbio:~$ sort test2 | uniq -c | awk 'BEGIN{OFS="\t";}{print $2, $1}' | sort -k2, 2n
c   1
d   1
e   1
b   2
a   3

# 第二列按數值大小排序
# 第二列相同的再按第一列的字母順序的逆序排序 (-r)
# 注意看前3行的順序與上一步結果的差異
ct@ehbio:~$ sort test2 | uniq -c | awk 'BEGIN{OFS="\t";}{print $2,$1}' | sort -k2,2n -k1,1r
e   1
d   1
c   1
b   2
a   3

FASTA序列提取

生成單行序列FASTA文件,提取特定基因的序列,最簡單的是使用grep命令。

grep在前面也提到過,以后還會經常提到,主要用途是匹配文件中的字符串,以此為基礎,進行一系列的操作。如果會使用正則表達式,將會非常強大。正則表達式版本很多,幾乎每種語言都有自己的規則,本文檔不會展開,用到哪個提哪個。

# 生成單行序列FASTA文件
ct@ehbio:~$ cat <<END >test.fasta
> >SOX2
> ACGAGGGACGCATCGGACGACTGCAGGACTGTC
> >POU5F1
> ACGAGGGACGCATCGGACGACTGCAGGACTGTC
> >NANOG
> CGGAAGGTAGTCGTCAGTGCAGCGAGTCCGT
> END
ct@ehbio:~$ cat test.fasta 
>SOX2
ACGAGGGACGCATCGGACGACTGCAGGACTGTC
>POU5F1
ACGAGGGACGCATCGGACGACTGCAGGACTGTC
>NANOG
CGGAAGGTAGTCGTCAGTGCAGCGAGTCCGT

# grep匹配含有SOX2的行
# -A 1 表示輸出的行中,包含匹配行的下一行 (A: after)
ct@ehbio:~$ grep -A 1 'SOX2' test.fasta 
>SOX2
ACGAGGGACGCATCGGACGACTGCAGGACTGTC

# 也可以使用AWK
# 先判斷當前行是不是 > 開頭,如果是,表示是序列名字行,替換掉大于號,取出名字。
# sub 替換, sub(被替換的部分,要替換成的,待替換字符串)
# 如果不以大于號開頭,則為序列行,存儲起來。
# seq[name]: 相當于建一個字典,name為key,序列為值。然后就可以使用name調取序列。
ct@ehbio:~$ awk 'BEGIN{OFS=FS="\t"}{if($0~/>/) {name=$0; sub(">", "", name);} else seq[name]=$0;}END{print ">SOX2"; print seq["SOX2"]}' test.fasta
>SOX2
ACGAGGGACGCATCGGACGACTGCAGGACTGTC

多行FASTA序列提取要麻煩些,一個辦法就是轉成單行序列,用上面的方式處理。

sedtr都為最常用的字符替換工具。

ct@ehbio:~$ cat <<END >test.fasta
> >SOX2
> ACGAGGGACGCATCGGACGACTGCAGGACTGTC
> ACGAGGGACGCATCGGACGACTGCAGGACTGTC
> ACGAGGGACGCATCGGACGACTGCAGGAC
> >POU5F1
> CGGAAGGTAGTCGTCAGTGCAGCGAGTCCGT
> CGGAAGGTAGTCGTCAGTGCAGCGAGTCC
> >NANOG
> ACGAGGGACGCATCGGACGACTGCAGGACTGTC
> ACGAGGGACGCATCGGACGACTGCAGG
> ACGAGGGACGCATCGGACGACTGCAGGACTGTC
> ACGAGGGACGCATCGGACGACTGCAGGACTGT
> END

# 給>號開頭的行的行尾加個TAB鍵,以便隔開名字和序列
# TAB鍵不可見,直接看看不大
# \(\)表示記錄匹配的內容,\1則表示()中記錄的匹配的內容
# 后面我們專門講sed
ct@ehbio:~$ sed 's/^\(>.*\)/\1\t/' test.fasta 
>SOX2   
ACGAGGGACGCATCGGACGACTGCAGGACTGTC
ACGAGGGACGCATCGGACGACTGCAGGACTGTC
ACGAGGGACGCATCGGACGACTGCAGGAC
>POU5F1 
CGGAAGGTAGTCGTCAGTGCAGCGAGTCCGT
CGGAAGGTAGTCGTCAGTGCAGCGAGTCC
>NANOG  
ACGAGGGACGCATCGGACGACTGCAGGACTGTC
ACGAGGGACGCATCGGACGACTGCAGG
ACGAGGGACGCATCGGACGACTGCAGGACTGTC
ACGAGGGACGCATCGGACGACTGCAGGACTGT

#使用cat -A 可以顯示文件中所有的符號
# ^I 表示tab鍵
# $表示行尾

ct@ehbio:~$ sed 's/^\(>.*\)/\1\t/' test.fasta | cat -A
>SOX2^I$
ACGAGGGACGCATCGGACGACTGCAGGACTGTC$
ACGAGGGACGCATCGGACGACTGCAGGACTGTC$
ACGAGGGACGCATCGGACGACTGCAGGAC$
>POU5F1^I$
CGGAAGGTAGTCGTCAGTGCAGCGAGTCCGT$
CGGAAGGTAGTCGTCAGTGCAGCGAGTCC$
>NANOG^I$
ACGAGGGACGCATCGGACGACTGCAGGACTGTC$
ACGAGGGACGCATCGGACGACTGCAGG$
ACGAGGGACGCATCGGACGACTGCAGGACTGTC$
ACGAGGGACGCATCGGACGACTGCAGGACTGT$

# 把所有的換行符替換為空格
# tr這個命令,前面提到過,若想不起來 `man tr`查看
# 主意第二個參數,引號內為空格。
ct@ehbio:~$ sed 's/^\(>.*\)/\1\t/' test.fasta | tr '\n' ' '
>SOX2    ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGGAC >POU5F1   CGGAAGGTAGTCGTCAGTGCAGCGAGTCCGT CGGAAGGTAGTCGTCAGTGCAGCGAGTCC >NANOG    ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGG ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGGACTGT 

# 把最后一個空格替換為換行符
ct@ehbio:~$ sed 's/^\(>.*\)/\1\t/' test.fasta | tr '\n' ' ' | sed -e 's/ $/\n/'
>SOX2    ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGGAC >POU5F1   CGGAAGGTAGTCGTCAGTGCAGCGAGTCCGT CGGAAGGTAGTCGTCAGTGCAGCGAGTCC >NANOG    ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGG ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGGACTGT

# 把  ' >'替換為換行符 注意被替換的是 空格+大于號
# 當連用多個替換命令時,使用-e 隔開
ct@ehbio:~$ sed 's/^\(>.*\)/\1\t/' test.fasta | tr '\n' ' ' | sed -e 's/ $/\n/' -e 's/ >/\n>/g'
>SOX2    ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGGAC
>POU5F1  CGGAAGGTAGTCGTCAGTGCAGCGAGTCCGT CGGAAGGTAGTCGTCAGTGCAGCGAGTCC
>NANOG   ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGG ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGGACTGT

# 把所有的空格替換掉
ct@ehbio:~$ sed 's/^\(>.*\)/\1\t/' test.fasta | tr '\n' ' ' | sed -e 's/ $/\n/' -e 's/ >/\n>/g' -e 's/ //g'
>SOX2   ACGAGGGACGCATCGGACGACTGCAGGACTGTCACGAGGGACGCATCGGACGACTGCAGGACTGTCACGAGGGACGCATCGGACGACTGCAGGAC
>POU5F1 CGGAAGGTAGTCGTCAGTGCAGCGAGTCCGTCGGAAGGTAGTCGTCAGTGCAGCGAGTCC
>NANOG  ACGAGGGACGCATCGGACGACTGCAGGACTGTCACGAGGGACGCATCGGACGACTGCAGGACGAGGGACGCATCGGACGACTGCAGGACTGTCACGAGGGACGCATCGGACGACTGCAGGACTGT

# 把TAB鍵轉換為換行符
ct@ehbio:~$ sed 's/^\(>.*\)/\1\t/' test.fasta | tr '\n' ' ' | sed -e 's/ $/\n/' -e 's/ >/\n>/g' -e 's/ //g' -e 's/\t/\n/g' 
>SOX2
ACGAGGGACGCATCGGACGACTGCAGGACTGTCACGAGGGACGCATCGGACGACTGCAGGACTGTCACGAGGGACGCATCGGACGACTGCAGGAC
>POU5F1
CGGAAGGTAGTCGTCAGTGCAGCGAGTCCGTCGGAAGGTAGTCGTCAGTGCAGCGAGTCC
>NANOG
ACGAGGGACGCATCGGACGACTGCAGGACTGTCACGAGGGACGCATCGGACGACTGCAGGACGAGGGACGCATCGGACGACTGCAGGACTGTCACGAGGGACGCATCGGACGACTGCAGGACTGT

或者簡單點,直接用前面的awk略微做下修改。

# 差別只在一點
# 對于單行fasta文件,只需要記錄一行,seq[name]=$0
# 對于多好fasta文件,需要把每一行序列都加到前面的序列上,seq[name]=seq[name]$0
ct@ehbio:~$ awk 'BEGIN{OFS=FS="\t"}{if($0~/>/) {name=$0; sub(">", "", name);} else seq[name]=seq[name]$0;}END{print ">SOX2"; print seq["SOX2"]}' test.fasta
>SOX2
ACGAGGGACGCATCGGACGACTGCAGGACTGTCACGAGGGACGCATCGGACGACTGCAGGACTGTCACGAGGGACGCATCGGACGACTGCAGGAC

命令運行監測

  1. 檢測命令的運行時間 time command
ct@ehbio:~$ time sleep 5

real    0m5.003s # 程序開始至結束的時間,包括其它進程占用的時間片和IO時間
user    0m0.001s # 進程真正執行占用CPU的時間, 
sys 0m0.002s     # 進程在內核中調用所消耗的CPU時間
user+sys是進程實際的CPU時間。如果多線程執行,這個時間可能大于Real。如果IO是瓶頸,則real會大于user+sys (單線程)。

  1. 查看正在運行的命令和其資源使用 top
  • top輸出界面第一行主要信息是負載顯示,分別是1分鐘、5分鐘、15分鐘前到現在的任務隊列的平均長度。
  • 一般與CPU數目相當為好,過大系統負載超額,反應慢。
  • 在top輸出界面輸入 u, 會提示輸入用戶名,以查看某個用戶的進程。
  • 重點關注的是%MEM列,查看系統占用的內存是否超出。
ct@ehbio:~$ top -a #按內存排序顯示

top - 09:02:11 up 224 days,  8:34,  30 users,  load average: 40, 33, 28
Tasks: 1561 total,   1 running, 1550 sleeping,   0 stopped,  10 zombie
Cpu(s):  0.6%us,  0.2%sy,  0.0%ni, 99.2%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  2642768880k total, 2094619800k used, 548149080k free,   4310240k buffers
Swap: 86472700k total, 73226016k used, 13246684k free, 193383748k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                  
32527 ct        20   0 2631m 1.7g 1332 S  0.0  0.7 100:34.87 rsem-run-em 
29273 ct        20   0 4094m 692m 3396 S  0.0  0.3  45:18.83 java -Xmx1000m
40148 mysql     20   0 21.9g 606m 6116 S  1.3  0.2   2536:06 /usr/sbin/mysqld
31040 ct        20   0 1887m  77m 2604 S  0.3  0.0 180:43.16 [celeryd: 

  1. 查看系統進程 ps auwx | grep 'process_name'

文件系統和磁盤信息監測

查看系統硬盤大小和分配

ct@ehbio:~$ df -h
Filesystem            Size  Used   Avail   Use% Mounted on
/dev/sda3             193G  112G     71G    62% /
tmpfs                 127G  104K    127G     1% /dev/shm
/dev/sda2             477M  102M    351M    23% /boot
/dev/sda1             200M  264K    200M     1% /boot/efi
/dev/mapper/ehbiobp1  137T   10T    127T     7% /ehbioB
/dev/mapper/ehbiocp1  137T   32T  104.8T    23% /ehbioC
/dev/mapper/ehbiodp1  137T   56T     81T    41% /ehbioD

ct@ehbio:~$ du -sh *
268M    blog
4.0K    browserMimic.py
5.6G    CAFE
386M    chip
73M class
4.0K    config.file
4.0K    do_not_del_r_test.Rmd
7.2M    ehbio
20K ehbio_logo.png
12K ehbio_weixin.jpg
4.0K    Grid_with_line.Rmd
8.0K    heatmap_nonlinear.pdf
8.0K    heatmap_nooutlier.pdf

軟件安裝

不同于windows,Linux下軟件安裝的方式比較多樣,有些也比較復雜。每種安裝方式都有自己的優點和局限,也都有可能遇到問題。在我們理解了原理之后,借助谷歌,可以更好地幫助解決問題。

系統包管理器安裝

軟件安裝最方便的、一般也不容易出問題的是利用系統自帶的包管理工具,可以解決大部分的依賴問題。

# centos
# 如果長時間沒更新,先運行下update
yum update
# 如果不知道軟件具體名字,可以先用一個關鍵字search一下, 選擇正式的名字
# 需要注意的是一般的服務器都是64 bit,需要選x86_64版本
yum search soft_name or soft_description
yum search soft_official_name

但也有一些不足,主要3點:

  1. 需要根用戶的權限。
  2. 如果系統版本老,安裝的軟件版本也會比較老。使用新版本有時又會發生沖突。
  3. 生物信息學中不少軟件不在系統的安裝源里面。

解決這些問題,就需要自己去軟件官網查找最新的分法包,又有兩種可能,一種是分法包直接就是編譯好的軟件,下載下來設置下可執行屬性并放入環境變量就可以運行了,如于blastbowtie這樣的工具。

另一種則是需要從源碼編譯安裝,下面主要講解下這個。

源碼編譯安裝

源碼編譯經典的三部曲configure, make, make install。如果不出問題,對著執行下來就安裝好了,也不一定知其所以然。但出了問題,就不是比較容易解決的。如果知道這背后的機制,還是會有幫助的。

  • configure是檢查系統的庫文件、類文件、依賴軟件是否存在以及它們的版本是否滿族需求,并根據實際檢測結果生成Makefile的工具。一般是一堆bash命令的組合。通常也需要在這一步配置一些參數。最常用的就是指定軟件的安裝目錄--prefix=/home/ct/soft/specific_name

  • make則是具體的編譯過程。編譯的語句都寫在了Makefile中。make默認編譯Makefile中出現的第一個target,也可以指定target編譯,并根據Makefile的設置方式依次編譯所有依賴的東西。

    Makefile通常的格式和布局如下,有興趣的可以自己去學,或者我們再出一個教程。

    # 假設當前文件夾下Makefile文件中內容如下 
    ct@ehbio:~$ cat Makefile
    # first: target名字
    # echo "compile first": target對應的命令,任何Linux命令都可以
    first:
        echo "compile first"
    all: first second
        echo "compile all"
    second:
        echo "compile second"
    
    # 直接運行make,會make第一個出現的target
    ct@ehbio:~$ make
    echo "compile first"
    compile first
    # make first與直接make相同,因為它出現在第一個 
    ct@ehbio:~$ make first
    echo "compile first"
    compile first
    # all依賴于first, second,因此make all會先執行make first, make second
    # 然后才是自己所代表的命令 
    ct@ehbio:~$ make all
    echo "compile first"
    compile first
    echo "compile second"
    compile second
    echo "compile all"
    compile all
    
    

有些軟件的安裝,在執行完make后就獲得了可執行程序,可以跳過make install的過程,只需要放入環境變量就可以運行了。但部分軟件還需要一些依賴關系,所以需要執行make install才算完成了完整的安裝。

  • make install通常是拷貝make編譯出來的可執行文件或者依賴的庫文件(如果有的話)到configure時的--prefix指定的目錄下。

  • 安裝好的軟件放入環境變量, 就可以快樂的運行了。

兩條注意:

  • 從源碼編譯最難解決的問題就是依賴的庫文件、頭文件、其它軟件的缺失或版本不匹配,沒有統一的解決辦法,原則就是缺啥補啥

  • 三部曲每一步的執行,屏幕上都會輸出比較多的信息,一定仔細看最后有沒有ERROR類的字樣,對判斷軟件有無安裝成功和下一步要怎么做會很有幫助。

Linux包的安裝的通用方式主要這些,后面還會提到兩種虛擬安裝方式,也都是為了簡化安裝而提出的。

Python包的安裝

在沒有Anaconda(或其前身canopy)出現之前,Python包以其管理混亂、安裝困難著稱。有了Anaconda后,不只python包的安裝簡單了,其它軟件的安裝也都方便了 (詳見后面Anaconda的兩個福利)。

  • 首先下載Anaconda的安裝包 https://www.continuum.io/downloads
  • Anaconda的安裝包做的很人性化,一個bash腳本,只要運行bash Anacond*x86_64.sh,然后按照提示操作就可以了。
  • 按照好后,設置或刷新下環境變量就可以使用了。
  • 此后再安裝python的包只需要執行pip install pakcage_nameconda install pakckage_name就可以了。
  • 這里唯一需要注意的就是確認使用的pythonpip確實是Anaconda安裝的pythonpip
    • which python查看使用的python命令。
    • 如果使用的還是系統默認的python,則需要檢查下環境變量的設置。

Anaconda的兩個福利

  1. 頭文件和庫文件庫

這是Anaconda安裝后的目錄結構

bin   envs  Examples  imports  lib    LICENSE.txt  pkgs     share  var
conda-meta  etc   gcc include  lib64  mkspecsplugins  ssl

其中lib目錄下,一部分是依賴的動態鏈接庫, .so文件;這也是在源碼編譯時最常見的攔路虎。通常,只需要把這個目錄放入環境變量LD_LIBRARY_PATH里面比如export LD_LIBARY_PATH=${LD_LIBARY_PATH}:anaconda_path/lib就可以解決問題。

cairo                    libitm.a              libQtScript.so.4
cmake                    libitm.la             libQtScript.so.4.8
engines                  libitm.so             libQtScript.so.4.8.7
gcc                      libitm.so.1           libQtScriptTools.la
gcj-4.8.5-14             libitm.so.1.0.0       libQtScriptTools.prl
glib-2.0                 libitm.spec           libQtScriptTools.so
libargtable2.a           libjpeg.a             libQtScriptTools.so.4
libargtable2.la          libjpeg.la            libQtScriptTools.so.4.8
libargtable2.so          libjpeg.so            libQtScriptTools.so.4.8.7
libargtable2.so.0        libjpeg.so.8          libQtSql.la
libargtable2.so.0.1.8    libjpeg.so.8.4.0      libQtSql.prl
libasan.a                libmkl_avx2.so        libQtSql.so
libasan.la               libmkl_avx512_mic.so  libQtSql.so.4
libasan_preinit.o        libmkl_avx512.so      libQtSql.so.4.8
libasan.so               libmkl_avx.so         libQtSql.so.4.8.7

  1. bioconda

bioconda提供了一個虛擬環境,方便軟件的編譯安裝。具體的我沒用過,可以讀下 徐洲更的生信軟件的好幫手-bioconda。

R包的安裝

R包的安裝具體看之前的R教程。

需要注意的也是依賴的軟件或庫文件的版本,同樣的Anaconda提供的lib庫也可以直接拿來用。

備注

文中凡是提到環境變量的地方都可鏈接到之前提到的環境變量使用的文章,請務必仔細讀兩遍。

如果軟件版本或依賴實在解決不了的,用Docker,虛擬出一個新的系統來解決,具體見。

Original link

原文鏈接 http://blog.genesino.com//2017/06/bash1/

微信公眾號

http://mp.weixin.qq.com/s/yKP1Kboji9N4p2Sl1Ovj0Q

AIRFLOWPYTHONCHENTONG
版權聲明:本文為博主原創文章,轉載請注明出處。

alipay.png
WeChatPay.png

</footer>

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容

  • Ubuntu的發音 Ubuntu,源于非洲祖魯人和科薩人的語言,發作 oo-boon-too 的音。了解發音是有意...
    螢火蟲de夢閱讀 99,458評論 9 467
  • linux資料總章2.1 1.0寫的不好抱歉 但是2.0已經改了很多 但是錯誤還是無法避免 以后資料會慢慢更新 大...
    數據革命閱讀 12,202評論 2 33
  • 下面是 騰訊云實驗室的教程, 方便自己練習和記錄這些命令,整合自己感興趣的三個教程收集在這里。 1 Linux基礎...
    Dino閱讀 1,013評論 0 50
  • .bat腳本基本命令語法 目錄 批處理的常見命令(未列舉的命令還比較多,請查閱幫助信息) 1、REM 和 :: 2...
    慶慶慶慶慶閱讀 8,175評論 1 19
  • 昨夜看見路燈下面人影密集簇群,而我卻散漫孤只。 眼淚蹣跚不下,后知后覺地了解到——生命里的陪伴不是長久便是一瞬。然...
    寧永顧閱讀 296評論 0 0