生成連續的自然數
seq 1 20
#輸出是1,2……20,分隔符是換行符
seq -s "," 1 20
#輸出是1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
分割符是,
seq -s " " -w 1 13
#輸出是01 02 03 04 05 06 07 08 09 10 11 12 13
這是寬格式數字,分隔符是空格
seq -w 1 20
#輸出01,02,……20 默認分割符是換行符,輸出的數字前面是有0的,用于寬格式。
查找指定大小的文件或文件夾
find . -name "*" -type f -size 0c | xargs -n 1 rm -rf
#刪除大小為0的文件夾
find . -name "*" -size 0c | xargs -n 1 rm -rf
#刪除大小為0的文件和文件夾
find . -name "*" -type f -size +10G | xargs -n 1 rm -rf
#找到大于10G的文件,并刪除。
find . -name "*.fpkm |xargs -i {} cp /tmp/fpkm/"
#復制以.fpkm結尾的文件到新的目錄/temp/fpkm目錄里。
sed使用shell變量
sed "s/${filename}/${filename}.new/g"
#使用shell變量的時候,需要使用雙引號。
行尾添加字符TAIL
sed 's/$/&TAIL/g'
行首添加字符HEAD
sed 's/^/HEAD/g'
行首和行尾同時添加
sed 's/^/START/;s/$/END/g'
匹配字符串行首添加其他字符串
sed -i "/gene/ s/^/g\*/"
file.txt #file.txt文件中包含gene
的行,行首添加上g*
字符串,這是直接修改源文件。
匹配奇數行或偶數行
cat 1.txt|sed -n '1~2p'
#獲取奇數行
cat 1.txt|sed -n '2~2p'
#獲取偶數行
匹配單引號(使用單引號包括\
來轉義'
)
sed 's/^>/sed -i '\''s\//g;' cds.fa
#替換的字符中有單引號
序列大小寫轉換
sed '/^[a-z]/s/[a-z]/\u&/g' novel.fa
#轉換fasta的序列從小寫變為大寫字母
sed '/^[A-Z]/s/[A-Z]/\l&/g' novel.fa
#轉換大寫為小寫字母
sed匹配指定字符之間的內容
cat kegg1.txt |sed 's/\[.*\]//g' >kegg_des
#匹配[]
中括號包含的內容,刪除中括號和其中的字符。
cat kegg1.txt |sed 's/\(.*\)//g' >kegg_des
#匹配()
小括號包含的內容,刪除小括號和其中的字符。
cat genome.fa|sed 's/CM[0-9]\{2,6\}//g;s/, whole genome shotgun sequence//g;' >genome.new.fa
#匹配CM后面是0-9的數字中2-6位數字,后一個是替換指定字符串, whole genome shotgun sequence
cat genome.fa|sed 's/CM[0-9]\{6\}//g;' >genome.new.fa
#匹配CM后面是0-9的數字中6位數字
獲取匹配行和前后行
grep -A 1 INT LTR.fa
#獲取包含INT的行和后一行(after)
grep -B 1 INT LTR.fa
#獲取包含INT的行和前一行(before)
grep -C 4 INT LTR.fa
#獲取包含INT的行和前后各4行(context)
去除重復行
sort -u file1
和cat file1|sort|uniq
的作用都是去除重復行,注意:uniq使用前,需要sort
uniq -c file1
顯示該行出現的次數
uniq -u file1
僅顯示出現一次的行列
uniq -d file1
僅顯示重復出現的行
刪除空白行
cat 1.txt|tr -s '\n'
要求文件格式是unix格式。
awk字符匹配
部分匹配
awk '$1 ~/Chr/ {print $0}' genome.gff
匹配第一列包含Chr字符的gff
awk '$1 !~/Chr/ {print $0}' genome.gff
匹配第一列不包含Chr的gff
awk '$1 ~/Chr/ && $4 <= 10000000 {print $0}' genome.gff
匹配各條Chr的前10M的gff
awk '$4 >=10000000 || $4 <= 100000000 {print $0}' genome.gff
匹配前10M或者大于100M的gff
精確匹配
awk '$4 ==10000000,$4 == 100000000 {print $0}' genome.gff
匹配10M到100M的gff 注意中間的逗號表示的是范圍,,
左右的就是對應的行的內容。提取的是這中間的行。
awk '$1 ==Chr1,$1 == Chr3 {print $0}' genome.gff
如果文件中是按照自然的Chr1,Chr2,Chr3這樣的順序排列,則會提取出第1列是Chr1到Chr3的所有的行。
awk if else判斷
awk '{if($4<$5)print $1,$2,$3,$4,$5,$6,"+",$8,$9;else print $1,$2,$3,$5,$4,$6,"-",$8,$9}' InGenome.gff3|tr " " "\t" >genome.gff3
查看gff文件第9列有哪些字段
awk 'BEGIN{FS=OFS="\t"} $3=="gene"{split($9, a, ";"); for(i in a){split(a[i], b, "="); if(++c[b[1]]==1) print b[1]}}' GCF_000001405.33_GRCh38.p7_genomic.gff
awk使用shell里面的變量
注意:awk使用shell變量的時候,前面用-v 變量名=值
聲明變量的賦值,后面使用的時候直接使用,不需要再使用$
,awk里面普通字符串需要使用"字符串"
,變量不能被雙引號包括。
abbr=$inputfile
awk -v abbr="${abbr}" '{print $1"_"abbr}' genome.id
awk輸出指定列到最后一列
分割符號是tab awk -F "\t" '{for (i=2;i<=NF;i++)printf("%s\t", $i);print ""}' file
分割符號是空格 awk -F " " '{for (i=2;i<=NF;i++)printf("%s ", $i);print ""}' file
awk里可以進行各種算數運算awk深入學習
awk '$3=="gene"{print $1,$4,$5,$5-$4}' test.bed
#第5列減去第4列的值
awk '$3=="gene"{print $1,$4,$5,log($5)/log(10)}' test.bed
#第5列取以10為底的對數
cat counts_num.bed| awk '{s[$1"\t"$2"\t"$3"\t"] += $4}END{ for(i in s){ print i, s[i] } }'
#計算出第1-3列行內容一致的第4列對應的行的和。
awk '$3=="gene"{sum+= $5-$4+1}END{print sum}' Spo.gff3
#計算所有基因的總長度
awk '$3=="gene"{sum+= $5-$4+1;i+=1}END{print sum/i}' Spo.gff3
#計算所有基因的平均長度
cat Spo.genome.gff3|awk '$3=="exon" {split($9,a,"="); print a[3]}'|sort|uniq -c|awk '{sum+=$1}END{print sum/NR}'
#統計基因的外顯子數量
cat Sp.genome.gff3|awk '$3=="gene"{split($9,a,"=");print a[2]}'
#第三列是gene,分割第9列,打印出分割后的第二個字符。
paste -d "\t" <(cat Sp.genome.gff3|awk '$3=="gene"{split($9,a,"=");print a[2]}') <(cat Sp.genome.gff3|awk '$3=="gene"{print $1"\t"$4"\t"$5}') >sp.genes
#提取一個基因組的所有基因和位置信息
cat counts_num.bed| awk '{s[$1"\t"$2"\t"$3"\t"] += $4;b[$1"\t"$2"\t"$3"\t"] += 1}END{ for(i in s){ print i, s[i],b[i] } }'|awk '{print $1"\t"$2"\t"$3"\t"log($4/$5)/log(10)}'
#提取第1-3列相同的行在第4列的值的和/對應的行數(即均值),然后再取以10為底的對數。其實$5就是基因密度。
輸出第一列中字符長度大于15的行
awk 'length($1)>15'
行列轉置
awk 'BEGIN{c=0;} {for(i=1;i<=NF;i++) {num[c,i] = $i;} c++;} END{ for(i=1;i<=NF;i++){str=""; for(j=0;j<NR;j++){ if(j>0){str = str" "} str= str""num[j,i]}printf("%s\n", str)} }' file
awk重命名fasta文件
awk 'FNR==NR{a[">"$1]=$2;next} $1 in a{ sub(/>/,">"a[$1]" ",$1)}1' name.list protein.fa
name.list需要有兩列,第一列是原來的ID,第二列是新的ID.protein.fa是需要重命名的fasta文件
awk只修改其中一列的內容后輸出所有的內容
awk -F "\t" 'OFS="\t"{if ($3==".")$3=$1"_"$2}1' AC11_L28.vcf
此處是當第三列是.
時,替換為第1列下劃線第2列。
awk -F "\t" 'OFS="\t"{if (NF>4)$3=$1"_"$2}1' AC11_L28.vcf
當列數大于4的時候,替換第3列的內容為第1列下劃線第2列。最后面的是1是個省略符,等價于 /.*
按行合并文件
cat file1 file2 >file0
按列合并文件
paste file1 file2 >file0
指定分隔符,按列合并文件
paste -d "\t" file1 file2 >file0
cut獲取指定列
cut -f 2-8 file1
獲取以tab分割的第2到8列
cut -d, -f 1-3 3.csv
獲取以,
分割的csv文件的第1到3列。
sed輸出文件指定行
sed -n '3,101p' 3.csv
獲取第3到101行。
cat 3.csv|sed '1,5d'
輸出刪除1-5行后的內容。
cat 3.csv|sed -e '3,$d'
刪除第3到最后1行
cat 3.csv|sed '2,5c No 2-5 number'
替換第2-5行的內容為No 2-5 number
cat 3.csv|sed '1c\test'
替換第1行的內容為test
cat 3.csv|sed '1a\test1'
在第1行下一行插入新的一行內容是test1
cat 3.csv|sed '1,3a\test1'
在第1-3行每行之后插入新一行
cat 3.csv|sed '1i/test1'
在第1行上一行插入新的一行內容是test1
cat 3.csv | sed -e '/motif/d'
刪除包含字符串’motif‘的行。
sed '1~2 s/aaa/bbb/' filename
修改奇數行的內容
sed '2~2 s/aaa/bbb/' filename
修改偶數行的內容
sed '3~5 s/aaa/bbb/' filename
修改第3行的內容,間隔5行的第3行,即3,8,13,18……行。(等差數列)
合并兩個文件(合并之前,先用sort排序)
join plant.tab 2.tab -t $'\t' >test.tab
指定輸出分隔符為tab
sort -k2 cdd.xls >cdd.xls.sort
根據第2列進行排序
sort -k1 cddid.tbl >cddid.sort
根據第1列進行排序
join -a 1 -1 2 -2 1 cdd.xls.sort cddid.sort -t $'\t' >cdd.final.xls
匹配第1個文件的第2列(-1 2
)和第2個文件的第1列(-2 1
)一致的行,同時輸出第1個文件中未匹配的行-a 1
,使用tab作為分割符$'\t'
join -o 1.1 2.3 cdd.xls.sort cddid.sort -t $'\t' >cdd
輸出匹配的第一個文件的第一列-o 1.1
和第二個文件的第3列2.3
匹配兩個文件
grep -f file1 file2
#匹配file1和file2中包含相同內容的行,輸出file2中這些行的內容。
grep -v -f file1 file2
#匹配file1和file2中不同內容的行,輸出file2中這些行的內容。
比較兩個文件的不同
comm -1 file1 file2
文件需要先sort,按列輸出不同。參數:-123 -1
表示不顯示只在file1中出現的列,-2
不顯示只在file2中出現的列,-3
不顯示file1和file2共有的列。
comm -3 file1 file2 '
文件需要先sort,輸出的是文件1和2共有的列,但是是分布在兩列,需要用sed替換tab。
diff log2013.log log2014.log -y -W 50
按行輸出兩個文件的不同,-y是以并列的方式顯示文件的異同之處 -W 50是指定欄寬。
檢測數據格式(檢測字段數是否一致) (datamash需要單獨安裝)
datamash check <test.tab
文件壓縮和解壓縮pigz pigz支持多線程,速度比gzip,bzip2快的多。
壓縮 pigz -k -9 -p 48 sample.bam > bam.tar.gz
-k是保留源文件 -9是指定壓縮比例,-11是最大壓縮比例,-0是最小壓縮比率。 -p 指定線程數量
打包壓縮 tar cvf - 目錄名 | pigz -k -9 -p 48 > bam.tar.gz
解壓縮unpigz -p 48 bam.tar.gz
多線程(大數據量的時候,能大大加快速度)
wget https://ftp.gnu.org/gnu/parallel/parallel-20190122.tar.bz2
tar jxvf parallel-20190122.tar.bz2
cd parallel-20190122
./configure -prefix=~/software/
make -j 8
make install
parallel支持標準輸出運行和命令調用運行。
cat jobs2run
jobs2run是要運行的命令腳本
bzip2 oldstuff.tar
oggenc music.flac
opusenc ambiance.wav
convert bigfile.tiff small.jpeg
ffmepg -i foo.avi -v:b 12000k foo.mp4
xsltproc --output build/tmp.fo style/dm.xsl src/tmp.xml
bzip2 archive.tar
多線程方式1:parallel --jobs 6 < jobs2run
多線程方式2:
bzip原始
cat bigfile.bin | bzip2 --best > compressedfile.bz2
bzip使用多線程
cat bigfile.bin | parallel --pipe --recend '' -k bzip2 --best > compressedfile.bz2
grep原始
grep pattern bigfile.txt
grep多線程
cat bigfile.txt | parallel --block 1M --pipe grep 'pattern'
1M是指每個cpu運行的100萬行。會把任務按照這個值,分配給各個cpu.
awk原始
cat rands20M.txt | awk '{s+=$1} END {print s}'
awk多線程
cat rands20M.txt | parallel --pipe awk \'{s+=\$1} END {print s}\' | awk '{s+=$1} END {print s}'
wc原始
wc -l bigfile.txt
wc多線程
cat bigfile.txt | parallel --pipe wc -l | awk '{s+=$1} END {print s}'
sed原始
sed s^old^new^g bigfile.txt
sed多線程
cat bigfile.txt | parallel --pipe sed s^old^new^g
速度對比
grep>awk>sed,cut
sed和cut速度比較慢。grep -f 也比較慢。sed不支持多線程,sed是按行操作,多線程會出問題。
多行fasta轉單行
cat test.fa | tr '\n' '\t' |sed 's/\t>/\n>/g'|sed 's/\t/\n/'|sed 's/\t//g'|sed '$s/$/$\n/'
先替換\n為\t.然后把\t>這個是頭部轉回\n>,注意第二次sed是只替換一次,就把每行第一個\t換成\n,然后把全局的\t刪除。第4個sed是在文件末尾添加上換行符(多次使用sed,速度慢)
awk '/^>/&&NR>1{print ""}{printf "%s",/^>/?$0"\n":$0}END{print ""}' test.fa
awk速度比較快
命令講解:
/^>/&&NR>1
匹配>
開頭且行號大于1的輸出換行符
/^>/?$0"\n":$0
是判斷是否>
開頭,是輸出本行和換行,否,則輸出本行。再用printf打印出來,但是這樣輸出的每個序列的末尾沒有換行符。所以才有前一個判斷只要不是第一行>
,都先輸出一個換行符。
END{print ""}
是在文檔最后輸出一個換行。
更多生物信息學的one liner https://github.com/stephenturner/oneliners#etc
文本行數超過3萬行,linux許多命令會報錯Argument list too long
。
解決方案,使用find
和xargs
參考地址。
find ./result_dir -name "*.kaks" |xargs cat |cut -f 1,3,4,5 | grep -v 'Sequence' >All_kaks.txt
find ./result_dir -name "*.axt.one-line"|while read id;do calculate_4DTV_correction.pl $id >${id%%one-line}4dtv;done
計算4DTv。
多進程并行運行
多線程工具parallel是系統自帶的,ParaFly一般的linux系統也自帶
ParaFly的有點就是,可以重跑。比如運行下面的命令,用于批量壓縮文件,當然pigz可以代替gzip,實現多線程
ls *.fq | while read fq; do echo "gzip ${fq}";done > gzip_fq.sh
nohup ParaFly -c gzip_fq.sh -CPU 8 -failed_cmds gzip_fq.sh.failed &
如果上面的壓縮命令失敗了,會輸出到gzip_fq.sh.failed文件,調整后再次nohup ParaFly -c gzip_fq.sh -CPU 8 -failed_cmds gzip_fq.sh.failed &
即可自動跳過已經運行成功的命令,只運行識別的命令。這在流程的斷點繼續分析中非常有用。
nohup parallel -j 8 < 2.sh &
一次運行腳本2.sh里的8行命令,即使用8個cpu。2.sh里是有n行需要并行執行的程序。
快速刪除空行的速度對比
genome.fa文件大小是4G.
運行命令 | 時間 |
---|---|
time grep -v '^$' genome.fa >genome.grep.fa | 13.45s |
time sed '/^$/d' genome.fa >genome.sed.fa | 19.565s |
time tr -s "n" genome.fa >genome.tr.fa | >3min |
time awk '/./ {print}' genome.fa >genome.awk.fa | 21.971s |
time sed -i '/^$/d' genome.fa | 18.693s |