批量处理--perl单行运行

问题:当我们用trimmomatic来过滤数据的时候,它是没有办法像有的工具一样,输入文件为 包含各个输入文件名字,这样问题就来了,我如果有很多个样品,该如何一步命令来处理呢?

java -jar /sam/trimmomatic/trimmomatic-0.32.jar PE -threads 12-phred64 -trimlog logfile input_forward.fq input_reverse.fqoutput_forward_paired.fq output_forward_unpaired.fq output_reverse_paired.fqoutput_reverse_unpaired.fq ILLUMINACLIP:1.adapter.list:2:30:10 LEADING:3TRAILING:3 SLIDINGWINDOW:4:15 MINLEN:36

方法:

  1. 用awk

  2. 或者perl -lne

    ls * |perl -lne ‘print “jar .. $_ &"’ |sh

  3. echo也行

    ls * |xargs -i echo java-jar …{} “&”|sh

一、perl单行运行

这里来介绍一下第二种方法:perl单行运行

与One-Liner相关的Perl命令行参数:
-0<</span>数字> (用8进制表示)指定记录分隔符($/变量),默认为换行 
-00 段落模式,即以连续换行为分隔符   
-0777 禁用分隔符,即将整个文件作为一个记录   
-a 自动分隔模式,用空格分隔$_并保存到@F中。相当于@F =split ''。分隔符可以使用-F参数指定  
-F 指定-a的分隔符,可以使用正则表达式  
-e 执行指定的脚本。  
-i<</span>扩展名> 原地替换文件,并将旧文件用指定的扩展名备份。不指定扩展名则不备份。 
-l 对输入内容自动chomp,对输出内容自动添加换行    
-n 自动循环,相当于while(<>) { 脚本; }    
-p 自动循环+自动输出,相当于while(<>) { 脚本; print; }

替换

将所有C程序中的foo替换成bar,旧文件备份成.bak
perl -p –i.bak -e 's/\bfoo\b/bar/g' *.c
很强大的功能,特别是在大程序中做重构。记得只有在UltraEdit用过。如果你不想备份,就直接写成 perl -p -i -e 或者更简单 perl -pie,恩,pie这个单词不错
将每个文件中出现的数值都加一
perl -i.bak -pe 's/(\d+)/ 1 + $1 /ge' file1 file2 ....
###(/d+)用来捕获数字,变量名为$1
将换行符\r\n替换成\n
perl -pie 's/\r\n/\n/g' file
同dos2unix命令。
将换行符\n替换成\r\n
perl -pie 's/\n/\r\n/g' file
同unix2dos命令。
取出文件的一部分
显示字段0-4和字段6,字段的分隔符是空格
perl -lane 'print "@F[0..4] $F[6]"' file
很好很强大,同 awk'print $1, $2, $3, $4, $5, $7'。参数名称lane也很好记。
如果字段分隔符不是空格而是冒号,则用
perl -F: -lane 'print "@F[0..4]\n"' /etc/passwd
显示START和END之间的部分
perl -ne 'print if /^START$/ .. /^END$/' file
恐怕这个操作只有sed才做得到了吧……
相反,不显示START和END之间的部分
perl -ne 'print unless /^START$/ .. /^END$/' file
显示开头50行:
perl -pe 'exit if $. > 50' file
同命令 head -n50
不显示开头10行:
perl -ne 'print unless 1 .. 10' file
显示15行到17行:
perl -ne 'print if 15 .. 17' file
每行取前80个字符:
perl -lne 'print substr($_, 0, 80) = ""' file
每行丢弃前10个字符:
perl -lne 'print substr($_, 10) = ""' file

**提取信息:**​

​##perl -lne 'print $1 if /Forward (\w+) Surviving/'nohup.out 
###perl -lne 'print "$1 $2" if /Pairs: (\d+)Both Surviving: (\d+)/' nohup.out   ​
####perl -lne 'print "$1 $2 $3" if /Pairs:(\d+) Both Surviving: (\d+) \((\d+.\d+%)\)/' nohup.out   
###perl -lne 'print "$1" if /-trimlog(.*)_logfile/' nohup.out   
####perl -lne 'print "$1" if /-trimlog(.*)_logfile/;print "$1 $2 $3" if /Pairs: (\d+) Both Surviving: (\d+)\((\d+.\d+%)\)/' nohup.out ###perl -lne 'print "$1\thhaa" if /-trimlog(.*)_logfile/;print "$1 $2 $3" if /Pairs: (\d+) Both Surviving: (\d+)\((\d+.\d+%)\)/' nohup.out    perl -ne 'print "$1\t" if /-trimlog(.*)_logfile/;print "$1\t$2\t$3\n" if /Pairs: (\d+) Both Surviving:(\d+) \((\d+.\d+%)\)/' nohup.out>1_trim_trimmomatic

批量替换

perl -p -i.bak -e 's/layout: post/#layout: post/g' *.md

搜索

查找comment字符串:
perl -ne 'print if /comment/' duptext
这个就是普通的grep命令了。
查找不含comment字符串的行:
perl -ne 'print unless /comment/' duptext
反向的grep,即grep -v。
查找包含comment或apple的行:
perl -ne 'print if /comment/ || /apple/' duptext
相同的功能就要用到egrep了,语法比较复杂,我不会……

计算

计算字段4和倒数第二字段之和:
perl -lane 'print $F[4] + $F[-2]'
要是用awk,就得写成 awk '{i=NF-1;print $5+$i}'
排序和反转
文件按行排序:
perl -e 'print sort <>' file
相当于简单的sort命令。
文件按段落排序:
perl -00 -e 'print sort <>' file
多个文件按文件内容排序,并返回合并后的文件:
perl -0777 -e 'print sort <>'file1 file2
文件按行反转:
perl -e 'print reverse <>' file1
相应的命令有吗?有……不过挺偏,tac(cat的反转)
数值计算
10进制转16进制:
perl -ne 'printf "%x\n",$_'
10进制转8进制:
perl -ne 'printf "%o\n",$_'
16进制转10进制:
perl -ne 'print hex($_)."\n"'
8进制转10进制:
perl -ne 'print oct($_)."\n"'
简易计算器。
perl -ne 'print eval_r($_)."\n"'
其他
启动交互式perl:
perl -de 1
查看包含路径的内容:
perl -le 'print for @INC'

二、我的案例

ls * |grep "fasta"|perl -lne 's/_R1.fasta//g;print' | less

ls * |grep "fasta"|perl -lne's/_R1.fasta//g;s/_R2.fasta//g;print' | sort |uniq | perl -lne 'print"java -jar /sam/trimmomatic/trimmomatic-0.32.jar PE -threads 12 -phred33-trimlog ${_}_logfile ${_}_R1.fasta ${_}_R2.fasta ${_}_output_forward_paired${_}_output_forward_unpaired ${_}_output_reverse_paired${_}_output_reverse_unpaired LEADING:25 TRAILING:25 SLIDINGWINDOW:4:25MINLEN:150 &"'>work.sh;
nohup sh work.sh&;

& 表示并行化运行

我的内存不够,所以只有去掉&

ls * |grep "fasta"|perl -lne's/_R1.fasta//g;s/_R2.fasta//g;print' | sort |uniq | perl -lne 'print"java -jar /sam/trimmomatic/trimmomatic-0.32.jar PE -threads 12 -phred33-trimlog ${_}_logfile ${_}_R1.fasta ${_}_R2.fasta ${_}_output_forward_paired${_}_output_forward_unpaired ${_}_output_reverse_paired${_}_output_reverse_unpaired LEADING:25 TRAILING:25 SLIDINGWINDOW:4:25MINLEN:150 "'>work.sh; 
nohup sh work.sh & ;

nohup sh work.sh & ; 在终端机后台工作,即使再次登录,命令还在执行

nohup sh work.sh ; 在终端机前台中工作


split -l 5 snps_for_pc.txt  input
ls |grep input|perl -lne 's/.txt//g;print'|perl -lne 'print "/home/qqin\/genoprime_dev/bin/genoprime.py design -t pc_primer -i ${_}.txt -w ${_}&"'>work.sh
nohup sh work.sh & ; 在终端机后台工作,即使再次登录,命令还在执行

批量拷贝指定文件

cat -v call_variant/vaiant_bams.tsv
看到^M这样的字符串,这是windows的换行符,需要被替换掉
dos2unix call_variant/vaiant_bams.tsv
cat  call_variant/vaiant_bams.tsv |perl -lne 'print "cp ./bam_new/${_}/${_}.sort.bam ./call_variant;"' >work.sh 
sh work.sh 

参考资料:

Perl之单行命令特技

药企,独角兽,苏州。团队长期招人,感兴趣的都可以发邮件聊聊:tiehan@sina.cn
个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn