Shell 命令1

查看当前目录下哪个文件占用空间最大?

1
2
3
du -h --max-depth=1
# 查看服务器磁盘空间使用情况
df -h

切割字符串

1
2
3
awk 'NR==1' seq.fasta > seq_need.fasta && sed -n '2,$p' seq.fasta | xargs | sed 's/ //g' | cut -c -start >> seq_need.fasta && sed -n '2,$p' seq.fasta | xargs | sed 's/ //g' | cut -c end- >> seq_need.fasta
# 注意 start > 1;
# 上面的命令直接提取 seq.fasta 103-end碱基到seq_need.fasta文件中

find

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
find dir -name "***"  # 在目录dir下查找文件名满足 *** 的文件;并打印
find ./ -name "*_mjw.*" # 在当前目录下查询还有 _mjw. 字段的文件
find dir -regex "***" # 基于正则表达式进行文件名匹配查找
find ./ -size 10k -ls # 表示查询文件大小在9k-10k之间的文件;-ls:表示详细显示查询到的文件信息
find -name april* fprint file 在当前目录下查找以april开始的文件,并把结果输出到file中
find -name ap* -o -name may* 查找以ap或may开头的文件
find . -name .svn | xargs rm -rf # 直接将查询到的文件删除
# 其他参数
---size:根据文件大小查询;文件大小前有+表示查找大于size的文件;-表示小于
---iname:表示文件名匹配不区分大小写
---type:根据文件类型查询;f--普通文件;d--目录;c--字符文件;b--块文件;l--符号链接文件;p--管道设备文件;s--套接字设备文件
# 组合查找参数
---a:相当于 && ,且
---o:相当于 || ,或
---not:相当于 !,非

echo

1
2
echo -e '\n'  # 输出换行;注意这里必须添加 -e 参数;-e 代表激活转义字符
# 使用 echo 输出代码块时,建议使用单引号;而双引号用在变量等其他地方

xargs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# xargs 命令可以捕获一个命令的输出,然后传递给另外一个命令;关键是可用于很多不支持管道 | 来传递参数
somecommand | xargs -item command
# 其他参数
-a file 从文件中读入作为 stdin
-e flag ,注意有的时候可能会是-E,flag必须是一个以空格分隔的标志,当xargs分析到含有flag这个标志的时候就停止。
-p 当每次执行一个argument的时候询问一次用户。
-n num 后面加次数,表示命令在执行的时候一次用的argument的个数,默认是用所有的。
-t 表示先打印命令,然后再执行。
-i 或者是-I,这得看linux支持了,将xargs的每项名称,一般是一行一行赋值给 {},可以用 {} 代替。
-r no-run-if-empty 当xargs的输入为空的时候则停止xargs,不用再去执行了。
-s num 命令行的最大字符数,指的是 xargs 后面那个命令的最大命令行字符数。
-L num 从标准输入一次读取 num 行送给 command 命令。
-l 同 -L。
-d delim 分隔符,默认的xargs分隔符是回车,argument的分隔符是空格,这里修改的是xargs的分隔符。
-x exit的意思,主要是配合-s使用。。
-P 修改最大的进程数,默认是1,为0时候为as many as it can ,这个例子我没有想到,应该平时都用不到的吧。

如何从第二行开始打印?

1
2
3
awk 'NR > 1{print $0}' file
# or
sed -n '2,$p' file

如何让多行转换成一行输出?

1
2
awk BEGIN{RS=EOF}'{gsub(/\n/," ");print}' file
sed ':a ; N;s/\n/ / ; t a ; ' file

AWK

1
2
3
awk 'NR==FNR{...}NR>FNR{...}'  file1 file2
## 或
awk 'NR==FNR{...}NR!=FNR{...}' file1 file2

读入file1的时候,已读入file1的记录数FNR一定等于awk已读入的总记录数NR,因为file1是awk读入的首个文件,故读入file1时执行前一个命令块{...},当读入file2的时候,已读入的总记录数NR一定>读入file2的记录数FNR,故读入file2时执行后一个命令块{...}

1
awk 'NR==FNR{...;next}{...}' file1 file2
读入file1时,满足NR==FNR,先执行前一个命令块,但因为其中有next命令,故后一个命令块{...}是不会执行的读入file2时,不满足NR==FNR,前一个命令块{..}不会执行,只执行后一个命令块{...}

多于三个文件的处理

当awk处理的文件超过两个时,显然上面那种方法就不适用了。因为读第3个文件或以上时,也满足NR>FNR (NR!=FNR),显然无法区分开来。所以就要用到更通用的方法了:

ARGIND 当前被处理参数标志:

1
awk 'ARGIND==1{...}ARGIND==2{...}ARGIND==3{...}... ' file1 file2 file3 ...
1
2
3
4
5
6
7
8
9
 ARGV 命令行参数数组:  awk 'FILENAME==ARGV[1]{...}FILENAME==ARGV[2]{...}FILENAME==ARGV[3]{...}...' file1 file2 file3 ...   
把文件名直接加入判断: awk 'FILENAME=="file1"{...}FILENAME=="file2"{...}FILENAME=="file3"{...}...' file1 file2 file3 ... #没有前两种通用

# 参考链接:https://linuxcmd.ee-fans.com/c/awk.html
# 说明:在linux下对文本和数据进行处理的一个常用且实用的工具;灵活性是 awk 最大的优势。
# awk 脚本由模式和操作组成
# 模式:正则表达式--关系表达式--模式匹配表达式--BEGIN语句块--pattern语句块--END语句块
# 操作:主要是由一个或者多个命令、函数、表达式组成,之间由换行符或者分号隔开,并位于大括号内
# 操作主要部分:变量/数组赋值--输出命令--内置函数--控制流语句

awk 脚本基本结构:

1
awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' file

工作原理:

1
2
3
4
5
6
7
8
1> 执行 BEGIN{ command } 语句块中的语句;
2> 从文件或者标准输入(stdin)读取一行,然后执行 pattern{ commands } 语句块,它会逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕
3> 当读至输入流末尾时,执行 END{ commands } 语句块。

# 语句块说明:
1> BEGIN语句块:在awk开始从输入流中读取行 之前 被执行;这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中。
2> END语句块:在awk从输入流中读取完所有的行 之后 即被执行,比如打印所有行的分析结果这类信息汇总都是在 END 语句块中完成,它也是一个可选语句块。
3> pattern语句块:中的通用命令是最重要的部分,它也是可选的。如果没有提供 pattern 语句块,则默认执行 {print} ,即打印每一个读取到的行,awk 读取的每一行都会执行该语句块。

awk 中的 print:当使用不带参数的 print 时,它就打印当前行;当print的参数是以 逗号 进行分隔时,打印时则以 空格 作为定界符;在awk的print语句块中的 双引号 是被当作拼接符使用。

{} 类似于一个循环体,会对文件中的每一行进行迭代,通常变量初始化语句(如:i=0)以及打印文件头部的语句放入 BEGIN 语句块中,将打印的结果等语句放在END语句块中。

awk 内置变量(预定义变量)

说明:[A][N][P][G]表示第一个支持变量的工具,[A]=awk、[N]=nawk、[P]=POSIXawk、[G]=gawk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    **$n**  当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段。 
**$0** 这个变量包含执行过程中当前行的文本内容。
[N] **ARGC** 命令行参数的数目。
[G] **ARGIND** 命令行中当前文件的位置(从0开始算)。
[N] **ARGV** 包含命令行参数的数组。
[G] **CONVFMT** 数字转换格式(默认值为%.6g)。
[P] **ENVIRON** 环境变量关联数组。
[N] **ERRNO** 最后一个系统错误的描述。
[G] **FIELDWIDTHS** 字段宽度列表(用空格键分隔)。
[A] **FILENAME** 当前输入文件的名。
[P] **FNR** 同NR,但相对于当前文件。
[A] **FS** 字段分隔符(默认是任何空格)。
[G] **IGNORECASE** 如果为真,则进行忽略大小写的匹配。
[A] **NF** 表示字段数,在执行过程中对应于当前的字段数。
[A] **NR** 表示记录数,在执行过程中对应于当前的行号。
[A] **OFMT** 数字的输出格式(默认值是%.6g)。
[A] **OFS** 输出字段分隔符(默认值是一个空格)。
[A] **ORS** 输出记录分隔符(默认值是一个换行符)。
[A] **RS** 记录分隔符(默认是一个换行符)。
[N] **RSTART** 由match函数所匹配的字符串的第一个位置。
[N] **RLENGTH** 由match函数所匹配的字符串的长度。
[N] **SUBSEP** 数组下标分隔符(默认值是34)。

将read_count文件当中的第一列和Annotation.xls第一列一样的用Annotation.xls的第7列替换

1
awk 'NR==FNR{a[$1]=$7}NR!=FNR{print a[$1],$2,$3,$4,$5,$6,$7}' Annotation.xls read_count

将xx文件当中的第一列以及第三列分别和hh以及zz第一列对应起来,分别取对应hh和zz第二列的值替换到xx文件当中

1
awk 'ARGIND==1{a[$1]=$2}ARGIND==2{b[$1]=$2}ARGIND==3{print a[$1],$2,b[$3]}' hh zz xx # ARGIND==1代表处理第一个文件  ARGIND==2代表处理第二个文件  ARGIND==3代表处理第三个文件

cut

1
2
3
# 设置分隔符
cut -d '**' -f1 file # 按 ** 分割文件,并打印第一列
cut -f2 file # 按 \t 分割文件,并打印第二列

延时命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 在明天15:30执行
at 15:30 tomorrow

# 在2019年10月20日15:30执行
at 15:30 10/20/19

# 在30分钟后执行
at now +30 minutes

atq # 列出等待中的延时任务
atrm # 撤销延时任务
atrm 1 # 撤销编号为1的延时任务

#### ctrl+D 退出