Shell常用命令

Shell是Unix操作系统下传统的用户和计算机的交互界面,也是控制系统的脚本语言。对于程序员来说,熟悉shell的使用是一门基本功,但有时又像一门暗器(快狠准),在这里记录一些平时工作生活中用到过的命令,温故知新,就算忘了也有个地方可以快速查询。如果没有,没关系,几乎所有命令都可以通过command --help来查看用法。

lsof

查看8080端口被哪个进程占用 lsof -i:8080

1
2
3
$ lsof -i:8080
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 30712 lc 31u IPv6 999925 0t0 TCP *:http-alt (LISTEN)

vi:%s

将文件中所有的字符串aaaa替换成bbbb,vi命令::%s/aaaa/bbbb/g

awk

awk在对数据分析并生成报告时尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
基本语法 awk '{pattern + action}' {filenames} 尽管操作可能会很复杂,但语法总是这样。几种常用示例:

以;为分隔符,输出第4列大于0的行。$n表示第n列,n=0表示一整行。

1
$ awk -F ';' '$4>0' test.dat

以;为分隔符,所有第4列大于0的值的和。

1
$ cat test.dat|awk -F ';' '{if($4<0)sum+=$4} END {print sum}' 

split

用于把文件分割成多份,使用起来很简单:split [-bl] file [prefix]

  • -b 表示对文件按大小进行切分。
  • -c 表示对文件按行数进行切分。
  • prefix 用于指定切分后的文件名前缀,可以不写,默认为xaa、xab、xac …

如原文件all.dat的大小为1.2M,共12801行。用-b进行切分:

1
2
3
4
5
$split -b 600k all.dat
$ls -lh
1.2M all.dat
600k xaa
554k xab

-l进行切分:

1
2
3
4
5
6
7
$split -l 5000 all.dat
$wc -l *
12801 all.dat
5000 xaa
5000 xab
2081 xac
25802 total

应用场景:有一个每天定时处理数据的任务,某一天突然发现数据量特别大,处理时间太长,这时可以把原数据分成多份,然后用多个线程同时处理数据,确保不会超出时间。

du / df

两个命令都可以用于查看文件空间的占用情况,df一般用于查看磁盘的使用情况,du一般用于查看文件夹的大小。

df -h 查看磁盘的使用情况,可以看到的信息如下。-h参数用于显示大小时把byte换算成K/M/G等可读单位。

1
2
3
4
5
6
7
8
9
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 7.9G 954M 6.6G 13% /
tmpfs 16G 0 16G 0% /lib/init/rw
udev 16G 120K 16G 1% /dev
tmpfs 16G 4.0K 16G 1% /dev/shm
/dev/sda8 1.8T 32G 1.7T 2% /home
/dev/sda7 7.9G 147M 7.8G 2% /tmp
/dev/sda6 7.9G 563M 7.0G 8% /var

du -sh查看当前目录的大小,du -sh *查看每个子目录的大小,-s参数表示显示总和,如果不带-s会显示所有子文件和文件夹的大小。

scp

远程文件传输,secure copy。与ssh命令使用相同的验证方法并且提供相同的安全性。scp实质相当于利用SSH协议来传输数据的cp命令。

常见的两种用法:

  • 本地文件拷贝到远程主机,scp /local/path user@remotehost:/home/path
  • 远程主机文件拷贝到本地,scp user@remotehost:/home/path /local/path

当需要指定ssh的端口时,用-P port注意P需要大写,因为-p已经被rcp命令使用。如果需要拷贝文件夹,带上-r参数。
-v和大多数其他命令一样,用来显示执行过程的详细信息。

1
2
$ scp -P 1046 star-test.dat [email protected]:/home/lc/
star-test.dat 100% 2250 2.2KB/s 00:00

grep

强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。grep全称是Global Regular Expression Print。

常用参数:

  • -c 只输出匹配的行数。
  • -v 排除[options]匹配的结果
  • -i 不区分大小写。
  • -l -L 只列出匹配/不匹配的文件名。
  • -w 只匹配整个单词,而不是字符串的一部分(如匹配”magic”,而不匹配”magical”)。
  • -n 结果中显示行号。

grep命令可以通过管道符号叠加使用,如:

1
2
3
4
5
6
7
8
$ cat a.txt
1
2
12
3
$ cat a.txt|grep -n [0-9]|grep -v 1
2:2
4:3

comm

用于对两个有序的文件进行比较。

这个命令的使用有个前提,就是比较的两个文件必须是有序
不带参数时,的效果如下(cat用来显示文件内容):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ cat a.txt
0
1
12
2
3
$ cat b.txt
12
13
20
$ comm a.txt b.txt
0
1
12
13
2
20
3

输出结果有三列:第一列只在a中出现,第二列只在b中出现,第三列在a,b中都出现。因此comm有三个对应的可选参数:

  • -1 不显示只在第一个文件中出现过的列,也就是不显示第一列。
  • -2 不显示只在第二个文件中出现过的列,也就是不显示第二列。
  • -3 不显示两个文件中都出现过的列,也就是不显示第三列。

应用场景:每天通过数据挖掘得到一批符合条件的用户,需要对他们进行某个操作,并且每个用户只能被操作一次,
而每天提供的用户没有经过去重,那么每天操作前需要对之前已经操作过的用户进行去重。
也就是例如文件done.txt是已经操作过的用户,new.txt是新拿到的用户,那么通过comm -13 done.txt new.txt > todo.txt就可以得到我们想要的结果。

sort

将文件中的每一个行作为一个单元进行比较。

默认不带参数的比较原则是从首字符向后,依次按字符的ASCII码进行比较,结果按升序输出。效果:

1
2
3
4
5
6
7
8
9
10
$ cat a.txt
1
2
2
12
$ sort a.txt
1
12
2
2

常用的参数:

  • -u 对结果进行去重。
  • -r 按降序输出结果。
  • -o 将结果存入指定的文件,由于sort默认把结果输出到标准输出,所以通常需要用>符号来把结果重定向输出到文件中。但是当你想把结果放到被比较的原文件中时,用重定向会把原文件清空。这是就需要通过-o来指定输出结果到原文件。
  • -n 按照数值进行排序。
  • -t -k 这两个一般同时使用,-t用来指定分隔符,-k表示分割后用来进行比较的列。
  • -d 只处理英文字母、数字、空格字符,忽略其他字符。
  • -f 忽略大小写。
  • -m 将几个排序好的文件进行合并。

应用场景:上面comm命令的场景中,新得到的文件应该先进行排序sort -u new.txt -o new.txt
操作完后应该把新操作的用户合并到已操作的用户中sort -m -u done.txt new.txt -o done.txt

cut

切割字符串,用于文件时,以每一行为单元处理。

cut的使用比较简单,常用的只有两个参数:

  • -d 指定分隔符,不指定时默认以制表符\t作为分隔符,通常与-f一起使用。
  • -f 目标被分隔成几段以后,用-f表示取出其中的某几段。
  • -c -b 分别表示已字符/字节为单位,取出指定的区间。

示例:

1
2
3
4
$ echo "1,2,3,4,5"|cut -d , -f 2-4
2,3,4
$ echo "1,2,3,4,5"|cut -c 2-4
,2,

sed

非交互式的编辑器,不会修改文件,把结果输出的屏幕。

sed的用法比较多,也比较复杂,下面只列举一下常用的用法:

1
2
3
4
5
6
$ cat a.txt
0
1
2
3
4

1.删除文件中的2~4行

1
2
3
$ sed '2,4d' a.txt
0
4

2.取出文件中的1~3行

1
2
3
4
$ sed -n '1,3p' a.txt
0
1
2

3.删除从包含1的行到第一个包含3的行

1
2
3
$ sed '/1/,/3/d' a.txt
0
4

注意:sed本身不会改变文件

paste

把文件以列的方式,进行合并。

两个常用参数:

  • -d 指定合并时的间隔符,不指定则默认为制表符\t
  • -s 将文件的列转换为行。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ cat a.txt
1

2
$ cat b.txt
3
4
$ paste -d ',' a.txt b.txt
1,3
,4
2,
$ paste -s b.txt
3 4
$ paste -s -d ',' b.txt
3,4

持续更新…