shell关于文件操作

一、如何将一个十进制的整数用2进制表示出来?

echo "obase=2;50" | bc

 

二、Linux下经常需要删除空白行,grep,sed,awk,tr等工具均可实现 

grep -v '^$' filename
sed '/^$/d' filename
awk '{if($0!="") print $0}' filename
tr -s '\n' < filename

 

三、shell中if 判断语句中的匹配模式

 =~ 表示匹配

if [[ $slave =~ "140$" ]]
then
    echo "end with 140"
fi

 

四、awk中split的用法

 有一个文件存在两域,第一域是基因名字,第二域是别名,别名存在多个,以|分割,要求将基因名和别名一一对应,如将下图转换成下下图的结果

   

awk -F"\t" -v OFS="\t" '{if($2~/\|/){len=split($2,a,"|");for(i=1;i<=len;i++)print $1,a[i]}else print $0}' input > result
#~表示第二域匹配到|,按|分割保存到数组a
#split()返回a的长度,并遍历a
#else未匹配到|则直接输出

 

 五、join对两个文件相同域进行合并操作

 现在有两个文件,其中两个文件有部分相同的域,如何筛选出这些域相同的记录,如A,B文件如下图:

 

 

 从上可以看出两个文件前四行有相同的域,那么我想把这些相同域的记录筛选出来,即前四行筛选出来,该怎么做呢?注意:join操作必须按指定的域进行排过序

join -1 1 -2 4 file_one file_two
'''
1:3113245|3144862 intergenic_region 1 3113245 3144862
1:3121377|3144862 intergenic_region 1 3121377 3144862
1:3404029|3404480 intron 1 3404029 3404480
1:3420575|3421901 intron 1 3420575 3421901
'''

#-1和-2指定连接的域

join -1 4 -2 1 two one
'''
1:3113245|3144862 1 3113245 3144862 intergenic_region
1:3121377|3144862 1 3121377 3144862 intergenic_region
1:3404029|3404480 1 3404029 3404480 intron
1:3420575|3421901 1 3420575 3421901 intron
'''

 

六、有两个关键词,如何将这两个关键词之间的行打印出来?

: comment
file:
1
2
3
3
4
5
6
7
7
8
9
10
comment

#将3和7之间的行打印出来
awk '/3/,/7/{print $0}' file
'''
3
3
4
5
6
7
'''
#可见将3和7之间的行一块儿打印出来了,其中3有2行,7只打印出一行
#如果不想打印出3和7关键词行
awk '/3/,/7/{if(i>1)print x;x=$0;i++}' file
'''
3
4
5
6
'''

awk '/3/,/7/{if(i>2)print x;x=$0;i++}' file
'''
4
5
6
'''

 

七、awk中substr()函数使用

 substr():截取字符串,返回从起始位置起,指定长度之子字符串;若未指定长度,则返回从起始位置到字符串末尾的子字符串。

 格式:

  substr(s,p) 返回字符串s中从p开始的后缀部分

  substr(s,p,n) 返回字符串s中从p开始长度为n的后缀部分

#将fastq转换为fasta
awk '{if(NR%4 == 1){print ">" substr($0, 2)}}{if(NR%4 == 2){print}}' fastq > fasta

 

八、有一文件

 如何根据红框中的值是否相同,将两行或者多行变成一行,GENE_ID列按逗号分隔,结果如下:

awk -F"GENE_ID=" 'BEGIN{tem=0}{split($2,array,";"); if($1!=tem){printf("\n%sGENE_ID=%s",$1,array[1]);tem=$1}else{printf(",%s",array[1])}}' paragon | sed '/^$/d' 

 

#coding=utf-8
import sys
in_file = sys.argv[1]
#需要保存上一行的name和line
#注意输入文件bed要先排序:sort -V your_bed
name_before = ''
line_before = ''
with open(in_file) as f1:
        for eachline in f1:
                array = eachline.strip().split('\t')
                if array[3] != name_before:
                        if line_before:
                                print line_before
                        gene_id = array[-1].strip().split(';')[0]
                        new_line = '\t'.join((array[0:-1] +  [gene_id]))
                        name_before = array[3]
                        line_before = new_line

                else:
                        gene_id = array[-1].strip().split(';')[0].split('=')[-1]
                        line_before = line_before + ',' + gene_id

        #print the last line
        print line_before

 九、如何提取字符串中的数字部分

 如执行上面的命令,想提取其中的数字部分:

pstree -Ap |  tr -cd "[0-9])" | sed 's/)/\n/g' | less

 -d表示删除,[0-9]表示所有数字,-c表示对条件取反,所以tr -cd "[0-9]"这句话的意思就是,剔除非数字的字符

 

十、一个文件vim编辑中文显示正常,more或者less显示乱码

 执行下面的命令试试:

cat data_20190306.csv | iconv -f GBK -t UTF-8 > data_20190306_new.csv

  如果vi中文乱码:

vi ~/.vimrc
#添加:set fileencodings=utf-8,gbk

 如果使用python打开文件报UnicodeDecodeError错误,则可以再linux下使用file命令,查看文件编码格式,然后open时候指定encoding参数,如:

Little-endian UTF-16 Unicode text, with CRLF, CR line terminators

说明文件是utf-16编码,并且是\n\r换行

 

 

十一、windows文件转换unix文件

 vi一个文件:

set ff?     #显示当前文件格式
set ff=unix     #设置成unix格式
set ff=dos #设置成dos格式

  或者dos2unix命令,但是得先安装

posted @ 2018-04-03 23:27  1直在路上1  阅读(472)  评论(0编辑  收藏  举报