Linux bash学习
更多生信和LInux學習,程序寫作,請掃描關注生信寶典。
https://mp.weixin.qq.com/mp/homepage?__biz=MzI5MTcwNjA4NQ==&hid=6&sn=667813e1f021e2cf155a74457b48d087&scene=18&uin=&key=&devicetype=Windows+UnKnow&version=62040549&lang=zh_CN&ascene=7&winzoom=1
本教程宗旨 (請仔細閱讀)
本教程不是一個完備的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.209Welcome 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忽略這個錯誤。
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<div class="se-preview-section-delimiter"></div>## 注意命令和參數之間的空格 ct@ehbio:~/data$ ls-l -bash: ls-l: 未找到命令 ct@ehbio:~$ ls -l 總用量 4<div class="se-preview-section-delimiter"></div>## d: dir; 表示data是個目錄<div class="se-preview-section-delimiter"></div>## rwx:表示目錄的權限,暫時忽略,或自己在線搜索 drwxrwxr-x 2 ct ct 4096 6月 8 14:52 data ct@ehbio:~$ ls -l data 總用量 4<div class="se-preview-section-delimiter"></div>## 開頭的`-`表示test.fa是個文件 -rw-rw-r-- 1 ct ct 284 6月 8 14:48 test.fa<div class="se-preview-section-delimiter"></div>查看寫入的文件的內容,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<div class="se-preview-section-delimiter"></div>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<div class="se-preview-section-delimiter"></div>另外less和more也可以用來查看文件,尤其是文件內容特別多的時候。
ct@ehbio:~/data$ less test.fa <div class="se-preview-section-delimiter"></div># q: 退出<div class="se-preview-section-delimiter"></div># 上下箭頭、空格翻頁<div class="se-preview-section-delimiter"></div>獲取可用命令行參數
前面使用的命令,有幾個用到了參數如ls -l, head -n 6等,需要注意的是命令跟參數之間要有空格。
終端運行man ls可以查看ls所有可用的參數,上下箭頭翻頁,按q退出查看。(man: manual, 手冊)
ct@ehbio:~/data$ man ls NAMEls - list directory contentsSYNOPSISls [OPTION]... [FILE]...DESCRIPTIONList 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, --alldo not ignore entries starting with .-A, --almost-alldo not list implied . and ..--authorwith -l, print the author of each file-b, --escapeprint C-style escapes for nongraphic characters....<div class="se-preview-section-delimiter"></div>文件上下翻轉和左右翻轉
兩個有意思的命令,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<div class="se-preview-section-delimiter"></div>其它新建文件的方式
nano類似于Windows下記事本的功能,nano filename就可以新建一個文件,并在里面寫內容;ctrl+x退出,根據提示按Y保存。
vim 功能更強大的文本編輯器。vim filename就可以新建一個文件, 敲擊鍵盤字母i,進入寫作模式。寫完后,敲擊鍵盤Esc, 退出寫作模式,然后輸入:w (會顯示在屏幕左下角),回車保存。vim的常用方法,以后會單寫一個,這里點到為止。
Linux下文件操作
常用的文件操作有移動文件到另一個文件夾、復制文件到另一個文件夾、文件重命名等。
cp (copy): 拷貝文件或文件夾 (cp -r 拷貝文件夾時的參數,遞歸拷貝)
<div class="se-preview-section-delimiter"></div># 列出當前目錄下有的文件和文件夾 ct@ehbio:~$ ls data<div class="se-preview-section-delimiter"></div># 新建一個文件夾 ct@ehbio:~$ mkdir ehbio_project<div class="se-preview-section-delimiter"></div># 列出當前目錄下有的文件和文件夾, 及其子文件夾的內容<div class="se-preview-section-delimiter"></div># data目錄下有一個文件,ehbio_project目錄下無文件 ct@ehbio:~$ ls * data: test.faehbio_project:<div class="se-preview-section-delimiter"></div># 拷貝data目錄下的文件test.fa到ehbio_project目錄下 ct@ehbio:~$ cp data/test.fa ehbio_project/<div class="se-preview-section-delimiter"></div># 列出當前目錄下有的文件和文件夾, 及其子文件夾的內容<div class="se-preview-section-delimiter"></div># data目錄下有一個文件,ehbio_project目錄下無文件 ct@ehbio:~$ ls * data: test.faehbio_project: test.fa<div class="se-preview-section-delimiter"></div>mv (move): 移動文件或文件夾
<div class="se-preview-section-delimiter"></div># 重命名data目錄下的文件test.fa為first.fa<div class="se-preview-section-delimiter"></div># mv除了可以移動文件,也可以做單個文件的重命名 ct@ehbio:~$ mv data/test.fa data/first.fa<div class="se-preview-section-delimiter"></div># 列出當前目錄下有的文件和文件夾, 及其子文件夾的內容 ct@ehbio:~$ ls * data: first.faehbio_project: test.fa<div class="se-preview-section-delimiter"></div>rename: 文件重命名 (常用于批量重命名,不同的系統可能用法略有不同,使用前先man rename查看使用方法)
<div class="se-preview-section-delimiter"></div># 進入另一個目錄 ct@ehbio:~$ cd ehbio_project/ ct@ehbio:~/ehbio_project$ ls test.fa<div class="se-preview-section-delimiter"></div># 給文件做一份拷貝 ct@ehbio:~/ehbio_project$ cp test.fa second.fa ct@ehbio:~/ehbio_project$ ls second.fa test.fa<div class="se-preview-section-delimiter"></div># 給文件多拷貝幾次,無聊的操作,就是為了給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<div class="se-preview-section-delimiter"></div># cp 后面需要2個參數,被拷貝的文件和要被拷貝到的目錄或文件<div class="se-preview-section-delimiter"></div># 出現下面的錯誤,表示缺少目標路徑或文件 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<div class="se-preview-section-delimiter"></div># 用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<div class="se-preview-section-delimiter"></div>ln (link): 給文件建立快捷方式 (ln -s source_file target 創建軟連接)。
在建立軟連接時,原文件要使用全路徑。全路徑指以/開頭的路徑。
建立軟連接,是為了在不增加硬盤存儲的情況下,簡化文件訪問方式的一個辦法。把其它文件夾下的文件鏈接到當前目錄,使用時只需要寫文件的名字就可以了,不需要再寫長串的目錄了。
../: 表示上一層目錄;../../: 表示上面兩層目錄
pwd (print current/working directory): 輸出當前所在的目錄
\``為鍵盤Esc下第一個按鍵 (與家目錄~`符號同一個鍵),寫在反引號內的命令會被運行,運行結果會放置在反引號所在的位置
<div class="se-preview-section-delimiter"></div># 建立軟連接,把當前目錄下的ehbio2.fa,鏈接到上一層目錄的data下面<div class="se-preview-section-delimiter"></div># 這是一個無效的軟連接, ct@ehbio:~/ehbio_project$ ln -s ehbio2.fa ../data<div class="se-preview-section-delimiter"></div># 在使用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<div class="se-preview-section-delimiter"></div># 輸出當前所在的目錄 ct@ehbio:~/ehbio_project$ pwd /home/ct/ehbio_project<div class="se-preview-section-delimiter"></div># 建立軟連接時,原始文件一定使用全路徑。全路徑指以/開頭的路徑。 ct@ehbio:~/ehbio_project$ ln -s /home/ct/ehbio_project/ehbio2.fa ../data ln: 無法創建符號鏈接" ../data/ehbio2.fa" : 文件已存在<div class="se-preview-section-delimiter"></div># 上面的錯誤信息時,已經存在這么一個鏈接了(雖然是無效的),但再建新的鏈接時還會提示<div class="se-preview-section-delimiter"></div># 使用`-f` (force)強制覆蓋已有的鏈接 ct@ehbio:~/ehbio_project$ ln -fs `pwd`/ehbio2.fa ../data<div class="se-preview-section-delimiter"></div># 再次查看時,就正常了。文件名下面沒有了背景色,并且有個右箭頭指向原始文件<div class="se-preview-section-delimiter"></div># `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<div class="se-preview-section-delimiter"></div># 通常為了簡化寫法,使用`pwd`代替全路徑<div class="se-preview-section-delimiter"></div># `為鍵盤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<div class="se-preview-section-delimiter"></div>Linux下命令的一些異常情況
命令不全:在命令沒有輸入完 (引號或括號沒有配對),就不小心按下了Enter鍵,終端會提示出一個>代表命令不完整,這是可以繼續輸入,也可以ctrl+c終止輸入,重新再來。(下面sed命令使用時,還有另外一種命令不全的問題)
ct@ehbio:~/ehbio_project$ rename 'ehbio2 >' ct@ehbio:~/ehbio_project$ rename 'ehbio2 > ^C ct@ehbio:~/ehbio_project$<div class="se-preview-section-delimiter"></div>文件名輸入錯誤: 多一個字母、少一個字母、大小寫問題
ct@ehbio:~/ehbio_project$ls ehbio2.fa ehbio3.fa ehbio4.fa ehbio.fa second.fa<div class="se-preview-section-delimiter"></div># 重命名沒有生效 ct@ehbio:~/ehbio_project$ rename 'ehbio2' 'ehbio5' ebio2.fa ct@ehbio:~/ehbio_project$ ls ehbio2.fa ehbio3.fa ehbio4.fa ehbio.fa second.fa<div class="se-preview-section-delimiter"></div># 仔細看是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<div class="se-preview-section-delimiter"></div>所在目錄不對: 訪問的文件不存在于當前目錄,而又沒有提供絕對路徑, 或軟連接失效
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<div class="se-preview-section-delimiter"></div># 當前目錄沒有ehbio2.fa ct@ehbio:~/ehbio_project$ less ehbio2.fa ehbio2.fa: 沒有那個文件或目錄<div class="se-preview-section-delimiter"></div># ehbio2.fa在上一層目錄的data目錄下 ct@ehbio:~/ehbio_project$ ls ../data/ehbio2.fa ../data/ehbio2.fa<div class="se-preview-section-delimiter"></div># 加上路徑依然訪問不了 ct@ehbio:~/ehbio_project$ less ../data/ehbio2.fa ../data/ehbio2.fa: 沒有那個文件或目錄<div class="se-preview-section-delimiter"></div># 上面的問題是軟連接失效,在之前的操作中刪掉了原始的ehbio2.fa,所以快捷方式失效<div class="se-preview-section-delimiter"></div># 正確的訪問 ct@ehbio:~/ehbio_project$ tail -n 3 ../data/first.fa ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC CAGGACAGGAGCTA end<div class="se-preview-section-delimiter"></div>Linux下文件內容操作
常用的文件內容操作有文件壓縮解壓縮、文件大小行數統計、文件內容查詢等。
gzip: 壓縮文件; gunzip: 解壓縮文件
<div class="se-preview-section-delimiter"></div># gzip -c 把壓縮的文件輸出到標準輸出 (一般是屏幕)<div class="se-preview-section-delimiter"></div># '>' 輸出重定向,輸出寫入文件ct@ehbio:~/ehbio_project$ gzip -c ehbio.fa >ehbio.fa.gz<div class="se-preview-section-delimiter"></div># 多了一個.gz文件 ct@ehbio:~/ehbio_project$ ls ehbio3.fa ehbio4.fa ehbio5.fa ehbio.fa ehbio.fa.gz second.fa<div class="se-preview-section-delimiter"></div>#解壓縮 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<div class="se-preview-section-delimiter"></div>wc (word count): 一般使用wc -l獲取文件的行數
<div class="se-preview-section-delimiter"></div># 輸出文件有14行 ct@ehbio:~/ehbio_project$ wc -l ehbio.fa 14 ehbio.fa<div class="se-preview-section-delimiter"></div>獲取文件中包含大于號 (>)的行, grep (print lines matching a pattern)。
grep的用法很多,支持正則表達式匹配,這里不展開,可以自己查閱資料,或在后期的教程涉及到時再學習。
替換文件中的字符: sed是一個功能強大的文件內容編輯工具,常用于替換、取得行號等操作。
<div class="se-preview-section-delimiter"></div># 第一個錯誤,漏掉了文件名<div class="se-preview-section-delimiter"></div># 程序靜止在這,等待用戶的進一步輸入<div class="se-preview-section-delimiter"></div># ctrl+c殺掉當前命令 ct@ehbio:~/ehbio_project$ sed 's/ HAHA//' | tail -n 3^C<div class="se-preview-section-delimiter"></div># 第二個錯誤,文件名和單引號之間沒有空格,使得sed判斷命令錯誤ct@ehbio:~/ehbio_project$ sed 's/ HAHA//'ehbio.fa | tail -n 3 sed:-e 表達式 #1,字符 11:“s”的未知選項<div class="se-preview-section-delimiter"></div># 正確操作,ct@ehbio:~/ehbio_project$ sed 's/ HAHA//' ehbio.fa | tail -n 4 >mYC ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC CAGGACAGGAGCTA end<div class="se-preview-section-delimiter"></div>另外一個方式,去除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<div class="se-preview-section-delimiter"></div>Linux終端常用快捷操作
- 命令或文件名自動補全:在輸入命令或文件名的前幾個字母后,按Tab鍵,系統會自動補全或提示補全
- 上下箭頭:使用上下箭頭可以回溯之前的命令,增加命令的重用,減少輸入工作量
- !加之前輸入過的命令的前幾個字母,快速獲取前面的命令
- ctrl+a回到命令的行首,用于修改常命令或注釋掉命令
- !! 表示上一條命令。
- 替換上一個命令中的字符,再運行一遍命令,用于需要對多個文件執行同樣的命令,又不想寫循環的情況
Linux下的標準輸入、輸出、重定向、管道
在Linux系統中,有4個特殊的符號,<, ‘>’, ‘|’, ‘-‘,在我們處理輸入和輸出時存在重要但具有迷惑性的作用。
默認Linux的命令的結果都是輸出到標準輸出,錯誤信息 (比如命令未找到或文件格式識別錯誤等) 輸出到標準錯誤,而標準輸出和標準錯誤默認都會顯示到屏幕上。
>表示重定向標準輸出,> filename就是把標準輸出存儲到文件filename里面。標準錯誤還是會顯示在屏幕上。
2 >&1 表示把標準錯誤重定向到標準輸出。Linux終端用2表示標準錯誤,1表示標準輸出。
- (短橫線):表示標準輸入,一般用于1個程序需要多個輸入的時候。
<標準輸入,后面可以跟可以產生輸出的命令,一般用于1個程序需要多個輸入的時候。
|管道符,表示把前一個命令的輸出作為后一個命令的輸入,前面也有一些展示例子。用于數據在不同的命令之間傳輸,用途是減少硬盤存取損耗。
下面我們通過一個程序stdout_error.sh來解釋上面的文字,內容如下
<div class="se-preview-section-delimiter"></div>#!/bin/bash echo "I am std output" <div class="se-preview-section-delimiter"></div># 下面是隨便寫的一個理論上不存在的命令, 理論上會報錯的。 unexisted_command<div class="se-preview-section-delimiter"></div>運行這個腳本
<div class="se-preview-section-delimiter"></div># 標準輸出和標準錯誤默認都會顯示到屏幕上 ct@ehbio:~$ bash stdout_error.sh I am std output stdout_error.sh: line 5: unexisted_command: command not found<div class="se-preview-section-delimiter"></div># >把結果輸入到了文件;標準錯誤還顯示在屏幕上 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<div class="se-preview-section-delimiter"></div># >把結果輸入到了文件; 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<div class="se-preview-section-delimiter"></div># 標準輸出和標準錯誤寫入同一個文件 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<div class="se-preview-section-delimiter"></div>下面看管道符和標準輸入的使用。
<div class="se-preview-section-delimiter"></div># 管道符的使用<div class="se-preview-section-delimiter"></div># 第一個命令的輸出作為第二個的輸入<div class="se-preview-section-delimiter"></div># 前面的例子中也有使用<div class="se-preview-section-delimiter"></div># tr: 是用于替換字符的,把空格替換為換行,文字就從一行變為了一列 ct@ehbio:~$ echo "1 2 3" | tr ' ' '\n' 1 2 3<div class="se-preview-section-delimiter"></div># cat命令之前也用過,輸出一段文字<div class="se-preview-section-delimiter"></div># diff是比較2個文件的差異的,需要2個參數<div class="se-preview-section-delimiter"></div># - (短橫線)表示上一個命令的輸出,傳遞給diff<div class="se-preview-section-delimiter"></div># < 表示其后的命令的輸出,也重定向給diff ct@ehbio:~$ cat <<END | diff - <(echo "1 2 3" | tr ' ' '\n') > 2 > 3 > 4 > END 0a1 > 1 3d3 < 4<div class="se-preview-section-delimiter"></div># 如果不使用管道和重定向標準輸入,程序是這么寫的<div class="se-preview-section-delimiter"></div># 先把第一部分存儲為1個文件 ct@ehbio:~$ cat <<END >firstfile 2 3 > 4 > END ct@ehbio:~$ less firstfile <div class="se-preview-section-delimiter"></div># 再把第二部分存儲為1個文件 ct@ehbio:~$ echo "1 2 3" | tr ' ' '\n' >secondfile<div class="se-preview-section-delimiter"></div># 然后比較 ct@ehbio:~$ diff firstfile secondfile 0a1 > 1 3d3 < 4<div class="se-preview-section-delimiter"></div>管道符的更多應用
ct@ehbio:~$ echo "actg aaaaa cccccg" | tr ' ' '\n' | wc -l 3<div class="se-preview-section-delimiter"></div># sed =:先輸出行號,再輸出每行的內容 ct@ehbio:~$ echo "a b c" | tr ' ' '\n' | sed = 1 a 2 b 3 c<div class="se-preview-section-delimiter"></div># 后面這個命令不太好解釋<div class="se-preview-section-delimiter"></div># sed = 同時輸出行號<div class="se-preview-section-delimiter"></div># N: 表示讀入下一行;sed命令每次只讀一行,加上N之后就是緩存了第2行,所有的操作都針對第一行;<div class="se-preview-section-delimiter"></div># s: 替換;把換行符替換為\t ct@ehbio:~$ echo "a b c" | tr ' ' '\n' | sed = | sed 'N;s/\n/\t/' 1 a 2 b 3 c<div class="se-preview-section-delimiter"></div># 后面這個命令不太好解釋<div class="se-preview-section-delimiter"></div># sed = 同時輸出行號<div class="se-preview-section-delimiter"></div># N: 表示讀入下一行;sed命令每次只讀一行,加上N之后就是緩存了第2行,所有的操作都針對第一行;<div class="se-preview-section-delimiter"></div># s: 替換;把讀取的奇數行行首加一個'>'(偶數行相當于被隱藏了) ct@ehbio:~$ echo "a b c" | tr ' ' '\n' | sed = | sed 'N;s/^/>/' >1 a >2 b >3 c<div class="se-preview-section-delimiter"></div># 把多條序列轉成FATSA格式<div class="se-preview-section-delimiter"></div># sed = 同時輸出行號<div class="se-preview-section-delimiter"></div># N: 表示讀入下一行;sed命令每次只讀一行,加上N之后就是緩存了第2行,所有的操作都針對第一行;<div class="se-preview-section-delimiter"></div># s: 替換;把讀取的奇數行行首加一個'>'(偶數行相當于被隱藏了)<div class="se-preview-section-delimiter"></div># 于是FASTA格式序列就出來了 ct@ehbio:~$ echo "actg aaaaa cccccg" | tr ' ' '\n' | sed = | sed 'N;s/^/>/' >1 actg >2 aaaaa >3 cccccg<div class="se-preview-section-delimiter"></div>文件的可執行屬性和環境變量
Linux下文件有一個特殊的屬性即可執行屬性,用來指示這個文件是一個可執行的腳本或可以運行的二進制文件。前面所提到的這些命令,都具有可執行屬性。
which: 表示查看命令的路徑。一般用于當我們想知道使用的命令來源于什么地方時,比如安裝了多個R或多個python,但又分不清用的是哪個時,which一下,立即明了。在這兒我們用which獲取的是可執行的命令所在的路徑,進而查看其屬性。
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l "`which cd`"<div class="se-preview-section-delimiter"></div>#rwx: 文件所有者可讀、可寫、可執行<div class="se-preview-section-delimiter"></div>#r-x: 文件所有者所在組其它成員可讀、可執行,不可修改<div class="se-preview-section-delimiter"></div>#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`"<div class="se-preview-section-delimiter"></div>#l: 代表軟連接<div class="se-preview-section-delimiter"></div>#軟連接自身是所有人可讀可寫,但具體的權限依賴于其鏈接的文件 lrwxrwxrwx. 1 root root 7 3月 22 15:04 /usr/bin/python -> python2 ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l "`which python2`"<div class="se-preview-section-delimiter"></div>#第二層鏈接 lrwxrwxrwx. 1 root root 9 3月 22 15:04 /usr/bin/python2 -> python2.7<div class="se-preview-section-delimiter"></div>#鏈接的原始文件 ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l "`which python2.7`" -rwxr-xr-x. 1 root root 7136 11月 6 2016 /usr/bin/python2.7<div class="se-preview-section-delimiter"></div>文件屬性rwx中r表示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查看其它參數使用。
<div class="se-preview-section-delimiter"></div># 新建個文件 ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ cat <<END >run.sh > echo " I am a script created by ehbio." > END<div class="se-preview-section-delimiter"></div># 查看其權限值 ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l run.sh -rw-rw-r-- 1 ct ct 39 6月 14 23:12 run.sh<div class="se-preview-section-delimiter"></div># 更改權限值 ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ chmod 755 run.sh<div class="se-preview-section-delimiter"></div># 查看其權限值<div class="se-preview-section-delimiter"></div># 注意多了3個x ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l run.sh -rwxr-xr-x 1 ct ct 39 6月 14 23:12 run.sh<div class="se-preview-section-delimiter"></div># 去除其它用戶的可執行權限 ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ chmod o-x run.sh <div class="se-preview-section-delimiter"></div># 注意看少了個x ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l run.sh -rwxr-xr-- 1 ct ct 39 6月 14 23:12 run.sh<div class="se-preview-section-delimiter"></div># 去除同組的可執行權限 ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ chmod g-x run.sh<div class="se-preview-section-delimiter"></div># 注意看又少了個x ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ ls -l run.sh -rwxr--r-- 1 ct ct 39 6月 14 23:12 run.sh<div class="se-preview-section-delimiter"></div># 去除所有人的可執行權限 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<div class="se-preview-section-delimiter"></div># 給所有人增加可執行權限 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<div class="se-preview-section-delimiter"></div>如果一個文件有了可執行權限,是不是就可以執行了,我們來檢測下。
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ run.sh -bash: run.sh: 未找到命令<div class="se-preview-section-delimiter"></div>事實上并非如此,輸入命令,回車后,提示命令未找打,這是為什么呢?
這就涉及到環境變量的概念,通俗的講,環境變量就是告訴電腦 (實際是操作系統)幾個目錄。這幾個目錄下存儲又可執行文件,如前面顯示的/usr/bin目錄,大部分的系統命令都在這個目錄下。
當我們輸入命令mkdir時,系統就會在環境變量所代表的幾個目錄從前都厚去查找,哪個里面有mkdir文件,然后去執行mkdir命令。
系統中環境變量的名字是PATH,其內容可通過下面的命令顯示 (根據操作系統不同和配置不同,略有差別,但格式是統一的,:分割的一堆路徑):
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ echo $PATH /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin<div class="se-preview-section-delimiter"></div>所以如果我們想讓自己的命令能被系統找到,就需要把命令所在的目錄加到環境變量里面,怎么操作呢?
加到環境變量的路徑必須是全路徑,全路徑指以/開頭或已~開頭的路徑。
<div class="se-preview-section-delimiter"></div># 加到環境變量的路徑必須是全路徑,全路徑指以/開頭或已~開頭的路徑<div class="se-preview-section-delimiter"></div># 注意第一個PATH不含$, 第二個PATH有$符號<div class="se-preview-section-delimiter"></div># 我們后面會講什么時候用$, 什么時候不用$ ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ export PATH=$PATH:/home/ct ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ echo $PATH /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ct<div class="se-preview-section-delimiter"></div>這時,我們在執行那個命令試試,成功運行了。
ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ run.sh I am a script created by ehbio.<div class="se-preview-section-delimiter"></div>所以在以后安裝了新的軟件,或者寫了新的腳本后,都把軟件的可執行程序和可執行的腳本所在的目錄,加到環境變量里面就可以了。
但是,在命令行中執行export,對環境變量所做的修改,只對當前終端有效,退出后就無效了。為了使得這一操作,長期有效,我們需要把這句話寫入一個文件中,一個登陸服務器就會被自動讀取的文件中。
對于普通用戶,在遠程登錄終端時,家目錄下的~/.bash_profile (不是~/.bashrc, 在本地登錄時才會被讀取)會自動被讀取,所以我們需要把export語句加入到這個文件中。
<div class="se-preview-section-delimiter"></div># 這是我的~/.bash_profile中的內容,主要是最好一行。可以連續的加入多個路徑。 if [ -f ~/.bashrc ]; then. ~/.bashrc fiif [ -f ~/.bash_aliases ]; then. ~/.bash_aliases fiexport PATH=$PATH:/home/ct:/home/bin:/home/soft/bowtie2/bin<div class="se-preview-section-delimiter"></div>前面提到,系統查找命令的順序是從環境變量的第一個目錄到最后一個目錄,在第一次碰到查詢的命令后,就調用執行。假如系統存在一個python命令,我們自己又安裝了一個python (假如在/home/ct/anaconda/bin目錄下),如果我們想執行自己的python程序,就需要把/home/ct/anaconda/bin寫在$PATH前面,如下
<div class="se-preview-section-delimiter"></div># 注意$PATH的順序ct@iZ8vb3e9jtel4m99ss6e7eZ:~$ export PATH=/home/ct/anaconda/bin:$PATH<div class="se-preview-section-delimiter"></div>至此,我們可以熟練使用環境變量來簡化命令的輸入過程了,因為如果沒有環境變量,我們就得需要運行/home/ct/anaconda/bin/python來運行python命令了。
環境變量這塊,自己多操作下,就會慢慢理解熟練了。
環境變量的補充
PATH只是眾多環境變量中的一個變量,用于存儲可執行文件所在的目錄,以便在用戶輸入命令時可以查詢的到。尤其是自己寫的腳本或安裝的程序,系統不會知道它們在哪個路徑下,需要我們去提供給系統這些新的路徑,學名叫設置環境變量。
此外常用到的環境變量還有LD_LIBARY_PATH: 指定動態鏈接庫 (so文件)的位置,一般在安裝軟件出錯時會用到;PYTHONPATH: 指定Python的安裝包的路徑;PERL5LIB: 指定perl的安裝包的路徑。
設置環境變量要注意2點:1. 設置新的環境變量時一般要包含原始的環境變量,不能覆蓋;2. 注意自己的目錄和系統環境變量的目錄的順序,想讓哪個先被找到,就先放哪個。
文件內容操作 (二)
文件排序
seq: 產生一系列的數字; man seq查看其具體使用。我們這使用seq產生下游分析所用到的輸入文件。
<div class="se-preview-section-delimiter"></div># 產生從1到10的數,步長為1 ct@ehbio:~$ seq 1 10 1 2 3 4 5 6 7 8 9 10<div class="se-preview-section-delimiter"></div># 產生從1到10的數,步長為1,用空格分割 ct@ehbio:~$ seq -s ' ' 1 10 1 2 3 4 5 6 7 8 9 10<div class="se-preview-section-delimiter"></div># 產生從1到10的數,步長為2<div class="se-preview-section-delimiter"></div># 如果有3個數,中間的數為步長,最后一個始終為最大值 ct@ehbio:~$ seq -s ' ' 1 2 10 1 3 5 7 9<div class="se-preview-section-delimiter"></div># 還記得前面提到的標準輸入和標準輸出吧<div class="se-preview-section-delimiter"></div># 后臺回復 標準輸入 查看 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<div class="se-preview-section-delimiter"></div>sort: 排序,默認按字符編碼排序。如果想按數字大小排序,需添加-n參數。
<div class="se-preview-section-delimiter"></div># 可能不符合預期的排序,系統首先排0,然后排1, 3, 6, 9 ct@ehbio:~$ sort test 0 12 15 15 3 3 6 9 9<div class="se-preview-section-delimiter"></div># 按數字大小排序 ct@ehbio:~$ sort -n test 0 3 3 6 9 9 12 15 15<div class="se-preview-section-delimiter"></div>sort -u: 去除重復的行,等同于sort | uniq。
ct@ehbio:~$ sort -nu test 0 3 6 9 12 15<div class="se-preview-section-delimiter"></div>sort file | uniq -d: 獲得重復的行。(d=duplication)
ct@ehbio:~$ sort -n test | uniq -d 3 9 15<div class="se-preview-section-delimiter"></div>sort file | uniq -c: 獲得每行重復的次數。
<div class="se-preview-section-delimiter"></div># 第一列為每行出現的次數,第二列為原始的行 ct@ehbio:~$ sort -n test | uniq -c1 02 31 62 91 122 15<div class="se-preview-section-delimiter"></div># 換一個文件看的更清楚 ct@ehbio:~$ cat <<END >test2 > a > b > c > b > a > e > d > a > END<div class="se-preview-section-delimiter"></div># 第一列為每行出現的次數,第二列為原始的行 ct@ehbio:~$ sort test2 | uniq -c 3 a 2 b 1 c 1 d 1 e<div class="se-preview-section-delimiter"></div># 在執行uniq操作前,文件要先排序,不然結果很詭異 ct@ehbio:~$ cat test2 | uniq -c 1 a 1 b 1 c 1 b 1 a 1 e 1 d 1 a<div class="se-preview-section-delimiter"></div>整理下uniq -c的結果,使得原始行在前,每行的計數在后。
awk是一個強大的文本處理工具,其處理數據模式為按行處理。每次讀入一行,進行操作。OFS: 輸出文件的列分隔符 (output file column separtor);FS為輸入文件的列分隔符 (默認為空白字符)。awk中的列從第1到n列,分別記錄為$1, $2 … $n。BEGIN表示在文件讀取前先設置基本參數;與之相對應的是END,只文件讀取完成之后進行操作。不以BEGIN, END開頭的{}就是文件讀取、處理的部分。
<div class="se-preview-section-delimiter"></div># 管道符還記得吧,后臺回復 管道 可查看<div class="se-preview-section-delimiter"></div># 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<div class="se-preview-section-delimiter"></div>對兩列文件,安照第二列進行排序, sort -k2,2n。
<div class="se-preview-section-delimiter"></div># 第二列按數值大小排序 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<div class="se-preview-section-delimiter"></div># 第二列按數值大小排序<div class="se-preview-section-delimiter"></div># 第二列相同的再按第一列的字母順序的逆序排序 (-r)<div class="se-preview-section-delimiter"></div># 注意看前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<div class="se-preview-section-delimiter"></div>FASTA序列提取
生成單行序列FASTA文件,提取特定基因的序列,最簡單的是使用grep命令。
grep在前面也提到過,以后還會經常提到,主要用途是匹配文件中的字符串,以此為基礎,進行一系列的操作。如果會使用正則表達式,將會非常強大。正則表達式版本很多,幾乎每種語言都有自己的規則,本文檔不會展開,用到哪個提哪個。
<div class="se-preview-section-delimiter"></div># 生成單行序列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<div class="se-preview-section-delimiter"></div># grep匹配含有SOX2的行<div class="se-preview-section-delimiter"></div># -A 1 表示輸出的行中,包含匹配行的下一行 (A: after) ct@ehbio:~$ grep -A 1 'SOX2' test.fasta >SOX2 ACGAGGGACGCATCGGACGACTGCAGGACTGTC<div class="se-preview-section-delimiter"></div># 也可以使用AWK<div class="se-preview-section-delimiter"></div># 先判斷當前行是不是 > 開頭,如果是,表示是序列名字行,替換掉大于號,取出名字。<div class="se-preview-section-delimiter"></div># sub 替換, sub(被替換的部分,要替換成的,待替換字符串)<div class="se-preview-section-delimiter"></div># 如果不以大于號開頭,則為序列行,存儲起來。<div class="se-preview-section-delimiter"></div># 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<div class="se-preview-section-delimiter"></div>多行FASTA序列提取要麻煩些,一個辦法就是轉成單行序列,用上面的方式處理。
sed和tr都為最常用的字符替換工具。
ct@ehbio:~$ cat <<END >test.fasta > >SOX2 > ACGAGGGACGCATCGGACGACTGCAGGACTGTC > ACGAGGGACGCATCGGACGACTGCAGGACTGTC > ACGAGGGACGCATCGGACGACTGCAGGAC > >POU5F1 > CGGAAGGTAGTCGTCAGTGCAGCGAGTCCGT > CGGAAGGTAGTCGTCAGTGCAGCGAGTCC > >NANOG > ACGAGGGACGCATCGGACGACTGCAGGACTGTC > ACGAGGGACGCATCGGACGACTGCAGG > ACGAGGGACGCATCGGACGACTGCAGGACTGTC > ACGAGGGACGCATCGGACGACTGCAGGACTGT > END<div class="se-preview-section-delimiter"></div># 給>號開頭的行的行尾加個TAB鍵,以便隔開名字和序列<div class="se-preview-section-delimiter"></div># TAB鍵不可見,直接看看不大<div class="se-preview-section-delimiter"></div># \(\)表示記錄匹配的內容,\1則表示()中記錄的匹配的內容<div class="se-preview-section-delimiter"></div># 后面我們專門講sed ct@ehbio:~$ sed 's/^\(>.*\)/\1\t/' test.fasta >SOX2 ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGGAC >POU5F1 CGGAAGGTAGTCGTCAGTGCAGCGAGTCCGT CGGAAGGTAGTCGTCAGTGCAGCGAGTCC >NANOG ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGG ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGGACTGT<div class="se-preview-section-delimiter"></div>#使用cat -A 可以顯示文件中所有的符號<div class="se-preview-section-delimiter"></div># ^I 表示tab鍵<div class="se-preview-section-delimiter"></div># $表示行尾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$<div class="se-preview-section-delimiter"></div># 把所有的換行符替換為空格<div class="se-preview-section-delimiter"></div># tr這個命令,前面提到過,若想不起來 `man tr`查看<div class="se-preview-section-delimiter"></div># 主意第二個參數,引號內為空格。 ct@ehbio:~$ sed 's/^\(>.*\)/\1\t/' test.fasta | tr '\n' ' ' >SOX2 ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGGAC >POU5F1 CGGAAGGTAGTCGTCAGTGCAGCGAGTCCGT CGGAAGGTAGTCGTCAGTGCAGCGAGTCC >NANOG ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGG ACGAGGGACGCATCGGACGACTGCAGGACTGTC ACGAGGGACGCATCGGACGACTGCAGGACTGT <div class="se-preview-section-delimiter"></div># 把最后一個空格替換為換行符 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<div class="se-preview-section-delimiter"></div># 把 ' >'替換為換行符 注意被替換的是 空格+大于號<div class="se-preview-section-delimiter"></div># 當連用多個替換命令時,使用-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<div class="se-preview-section-delimiter"></div># 把所有的空格替換掉 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<div class="se-preview-section-delimiter"></div># 把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<div class="se-preview-section-delimiter"></div>或者簡單點,直接用前面的awk略微做下修改。
<div class="se-preview-section-delimiter"></div># 差別只在一點<div class="se-preview-section-delimiter"></div># 對于單行fasta文件,只需要記錄一行,seq[name]=$0<div class="se-preview-section-delimiter"></div># 對于多好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<div class="se-preview-section-delimiter"></div>命令運行監測
查看正在運行的命令和其資源使用 top
- top輸出界面第一行主要信息是負載顯示,分別是1分鐘、5分鐘、15分鐘前到現在的任務隊列的平均長度。
- 一般與CPU數目相當為好,過大系統負載超額,反應慢。
- 在top輸出界面輸入 u, 會提示輸入用戶名,以查看某個用戶的進程。
- 重點關注的是%MEM列,查看系統占用的內存是否超出。
文件系統和磁盤信息監測
查看系統硬盤大小和分配
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<div class="se-preview-section-delimiter"></div> 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<div class="se-preview-section-delimiter"></div>軟件安裝
不同于windows,Linux下軟件安裝的方式比較多樣,有些也比較復雜。每種安裝方式都有自己的優點和局限,也都有可能遇到問題。在我們理解了原理之后,借助谷歌,可以更好地幫助解決問題。
系統包管理器安裝
軟件安裝最方便的、一般也不容易出問題的是利用系統自帶的包管理工具,可以解決大部分的依賴問題。
<div class="se-preview-section-delimiter"></div># centos<div class="se-preview-section-delimiter"></div># 如果長時間沒更新,先運行下update yum update<div class="se-preview-section-delimiter"></div># 如果不知道軟件具體名字,可以先用一個關鍵字search一下, 選擇正式的名字<div class="se-preview-section-delimiter"></div># 需要注意的是一般的服務器都是64 bit,需要選x86_64版本 yum search soft_name or soft_description yum search soft_official_name<div class="se-preview-section-delimiter"></div>但也有一些不足,主要3點:
解決這些問題,就需要自己去軟件官網查找最新的分法包,又有兩種可能,一種是分法包直接就是編譯好的軟件,下載下來設置下可執行屬性并放入環境變量就可以運行了,如于blast或bowtie這樣的工具。
另一種則是需要從源碼編譯安裝,下面主要講解下這個。
源碼編譯安裝
源碼編譯經典的三部曲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第一個出現的targetct@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_name或conda install pakckage_name就可以了。
- 這里唯一需要注意的就是確認使用的python或pip確實是Anaconda安裝的python或pip。
- which python查看使用的python命令。
- 如果使用的還是系統默認的python,則需要檢查下環境變量的設置。
Anaconda的兩個福利
這是Anaconda安裝后的目錄結構
bin envs Examples imports lib LICENSE.txt pkgs share var conda-meta etc gcc include lib64 mkspecsplugins ssl<div class="se-preview-section-delimiter"></div>其中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.7bioconda提供了一個虛擬環境,方便軟件的編譯安裝。具體的我沒用過,可以讀下 徐洲更的生信軟件的好幫手-bioconda。
R包的安裝
R包的安裝具體看之前的R教程。
需要注意的也是依賴的軟件或庫文件的版本,同樣的Anaconda提供的lib庫也可以直接拿來用。
備注
文中凡是提到環境變量的地方都可鏈接到之前提到的環境變量使用的文章,請務必仔細讀兩遍。
如果軟件版本或依賴實在解決不了的,用Docker,虛擬出一個新的系統來解決,具體見。
Original link
原文鏈接 http://blog.genesino.com//2017/06/bash1/
微信公眾號
http://mp.weixin.qq.com/s/yKP1Kboji9N4p2Sl1Ovj0Q
總結
以上是生活随笔為你收集整理的Linux bash学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 199的Eagle一点都不香了!Pics
- 下一篇: TV Distortion Bundle