linux常用命令

linux常用命令有:grep, awk, ps等待.

ls

ls用于显示指定工作目录之下的内容。列出目前工作目录所含之文件及子目录。

ls -F在列出的文件名称后加一符号;例如可执行档则加 “*”, 目录则加 “/“,“@”表示符号链接,“|”表示命令管道FIFO,“=”表示sockets套接字。当文件为普通文件时,不输出任何标识符
ls-a 显示所有文件及目录 (ls内定将文件名或目录名称开头为”.”的视为隐藏档,不会列出) ls -l 除文件名称外,亦将文件型态、权限、拥有者、文件大小等资讯详细列出
ls -r 将文件以相反次序显示(原定依英文字母次序)
ls -t 将文件依建立时间之先后次序列出
ls -Als -a ,但不列出 “.” (目前目录) 及 “..” (父目录)
ls -i查看文件的inode号

touch

touch可以创建一个空文件。同时该命令可以用于改变文件的修改时间。如果指定的文件不存在就创建它,否则就修改该文件的修改时间。但是该文件并不会将有内容的文件变为空文件。

cp

复制空文件
/dev/null是空设备。所有写向这个文件的输出都将被丢弃,而读这个设备会立刻返回一个文件尾标志。所以在cp命令里可以把它用作复制空文件的源文件。

1
2
3
4
5
6
7
# 复制空文件
xixi2@xixi2:~/liunx_prac$ sudo cp /dev/null null.txt

xixi2@xixi2:~/liunx_prac$ ls -lF null.txt
-rw-r--r-- 1 root root 0 10月 9 17:57 null.txt

xixi2@xixi2:~/liunx_prac$

ps

ps 命令是最常用的监控进程的命令,通过此命令可以查看系统中所有运行进程的详细信息。
ps 命令的基本格式如下:

1
2
3
4
5
#查看系统中所有的进程,使用 BS 操作系统格式
[root@localhost ~]# ps aux

#查看系统中所有的进程,使用 Linux 标准命令格式
[root@localhost ~]# ps -le

选项:

a:显示一个终端的所有进程,除会话引线外;
u:显示进程的归属用户及内存的使用情况;
x:显示没有控制终端的进程;
-l:长格式显示更加详细的信息;
-e:显示所有进程;

可以看到,ps 命令有些与众不同,它的部分选项不能加入”-“,比如命令”ps aux”,其中”aux”是选项,但是前面不能带“-”。
大家如果执行 “man ps” 命令,则会发现 ps 命令的帮助为了适应不同的类 UNIX 系统,可用格式非常多,不方便记忆。所以,我建议大家记忆几个固定选项即可。比如:
“ps aux” 可以查看系统中所有的进程“ps -le” 可以查看系统中所有的进程,而且还能看到进程的父进程的 PID 和进程优先级“ps -l” 只能看到当前 Shell 产生的进程

ps aux

ps aux命令列出的各字段名及其含义

1
2
3
4
5
6
# 执行ps aux并输出其结果的前4行
xixi2@xixi2:~/liunx_prac$ ps aux |head -n 4
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 225552 9252 ? Ss 16:11 0:03 /sbin/init splash
root 2 0.0 0.0 0 0 ? S 16:11 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? I< 16:11 0:00 [rcu_gp]
表头 含义
USER 该进程是由哪个用户产生的。
PID 进程的 ID。
%CPU 该进程占用 CPU 资源的百分比,占用的百分比越高,进程越耗费资源。
%MEM 该进程占用物理内存的百分比,占用的百分比越高,进程越耗费资源。
VSZ 该进程占用虚拟内存的大小,单位为 KB。
RSS 该进程占用实际物理内存的大小,单位为 KB。
TTY 该进程是在哪个终端运行的。其中,tty1 ~ tty7 代表本地控制台终端(可以通过 Alt+F1 ~ F7 快捷键切换不同的终端),tty1~tty6 是本地的字符界面终端,tty7 是图形终端。pts/0 ~ 255 代表虚拟终端,一般是远程连接的终端,第一个远程连接占用 pts/0,第二个远程连接占用 pts/1,依次増长。
STAT 进程状态。常见的状态有以下几种:-D:不可被唤醒的睡眠状态,通常用于 I/O 情况。-R:该进程正在运行。-S:该进程处于睡眠状态,可被唤醒。-T:停止状态,可能是在后台暂停或进程处于除错状态。-W:内存交互状态(从 2.6 内核开始无效)。-X:死掉的进程(应该不会出现)。-Z:僵尸进程。进程已经中止,但是部分程序还在内存当中。-<:高优先级(以下状态在 BSD 格式中出现)。-N:低优先级。-L:被锁入内存。-s:包含子进程。-l:多线程(小写 L)。-+:位于后台。
START 该进程的启动时间。
TIME 该进程占用 CPU 的运算时间,注意不是系统时间。
COMMAND 产生此进程的命令名。

ps -le

1
2
3
4
5
6
# 执行ps -le并输出其结果的前4行
xixi2@xixi2:~/liunx_prac$ ps -le | head -n 4
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 1 0 0 80 0 - 56388 - ? 00:00:03 systemd
1 S 0 2 0 0 80 0 - 0 - ? 00:00:00 kthreadd
1 I 0 3 2 0 60 -20 - 0 - ? 00:00:00 rcu_gp

各字段含义

表头 含义
F 进程标志,说明进程的权限,常见的标志有两个: 1:进程可以被复制,但是不能被执行;4:进程使用超级用户权限;
S 进程状态。具体的状态和”psaux”命令中的 STAT 状态一致;
UID 运行此进程的用户的 ID;
PID 进程的 ID;
PPID 父进程的 ID;
C 该进程的 CPU 使用率,单位是百分比;
PRI 进程的优先级,数值越小,该进程的优先级越高,越早被 CPU 执行;
NI 进程的优先级,数值越小,该进程越早被执行;
ADDR 该进程在内存的哪个位置;
SZ 该进程占用多大内存;
WCHAN 该进程是否运行。”-“代表正在运行;
TTY 该进程由哪个终端产生;
TIME 该进程占用 CPU 的运算时间,注意不是系统时间;
CMD 产生此进程的命令名;

kill

kill

pkill

killall

通过端口9190找到两个进程,然后使用killall杀死这两个进程。

1
2
3
4
xixi2@xixi2:~$ ps -ef | grep 9190 | grep -v "grep"
xixi2 29417 29000 0 14:54 pts/5 00:00:00 ./echo_client 127.0.0.1 9190
xixi2 29419 29016 0 14:54 pts/6 00:00:00 ./echo_client 127.0.0.1 9190
xixi2@xixi2:~$ killall "echo_client"

echo

单引号会把所有字符看作是普通字符,双引号会无视通配符,但是会解释”$”,”",”`”这三种特殊符号,不加引号则会解释所有特殊字符。

wc

1
2
3
4
5
6
7
8
$ wc testfile           # testfile文件的统计信息  
3 92 598 testfile # testfile文件的行数为3、单词数92、字节数598

$ wc testfile testfile_1 testfile_2 #统计三个文件的信息
3 92 598 testfile #第一个文件行数为3、单词数92、字节数598
9 18 78 testfile_1 #第二个文件的行数为9、单词数18、字节数78
3 6 32 testfile_2 #第三个文件的行数为3、单词数6、字节数32
15 116 708 总用量 #三个文件总共的行数为15、单词数116、字节数708
  • -c或–bytes或–chars 只显示Bytes数。
  • -l或–lines 只显示行数。
  • -w或–words 只显示字数。

grep

  • grep --color选项,高亮要查找的字符串.
    如,在/etc/passwd文件中查找某个字符串出现的行
1
2
root@root:~$ grep --color "la" /etc/passwd
gdm:x:121:125:Gnome Display Manager:/var/lib/gdm3:/bin/false # 在我的机器上的结果
  • grep -v选项,实现反查效果,显示出所有不包含被查询字符串的行.

    1
    2
    3
    4
    5
    grep -v "la" /etc/passwd

    # 在我的机器上的执行结果
    sshd:x:123:65534::/run/sshd:/usr/sbin/nologin
    nvidia-persistenced:x:124:129:NVIDIA Persistence Daemon,,,:/nonexistent:/sbin/nologin
  • grep 展示行号和统计行数

    • 使用-n选项,grep不仅能搜索到字符串,还能展示出它们位于文件的第几行.
    • 使用-c选项,grep可以统计搜索结果中的总行数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    root@root:~$ grep -n "la" /etc/passwd

    # 行首的40表示出现的行号
    40:gdm:x:121:125:Gnome Display Manager:/var/lib/gdm3:/bin/false


    root@root:~$ grep -c "la" /etc/passwd
    1
    root@root:~$ grep -c "var" /etc/passwd
    22
  • grep可以环顾四周

    • 在输出时,同时输出搜索结果相邻的行也输出出来.
    • -A number 表示输出搜索结果下面的行(number表示要输出的行数)
      • A是after的缩写
    • -B number 表示输出搜索结果上面的行(number表示要输出的行数)
      • B是before的缩写
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    root@root:~$ grep -A 1 "la" /etc/passwd
    gdm:x:121:125:Gnome Display Manager:/var/lib/gdm3:/bin/false
    root:x:1000:1000:root,,,:/home/root:/bin/bash

    root@root:~$ grep -n -A 2 "la" /etc/passwd
    40:gdm:x:121:125:Gnome Display Manager:/var/lib/gdm3:/bin/false
    41-root:x:1000:1000:root,,,:/home/root:/bin/bash
    42-redis:x:122:128::/var/lib/redis:/usr/sbin/nologin

    root@root:~$ grep -n -A 1 -B 1 "la" /etc/passwd
    39-gnome-initial-setup:x:120:65534::/run/gnome-initial-setup/:/bin/false
    40:gdm:x:121:125:Gnome Display Manager:/var/lib/gdm3:/bin/false
    41-root:x:1000:1000:root,,,:/home/root:/bin/bash
  • grep 不区分大小写

    • grep -i选项不区分大小写,提高搜索命中的概率
    1
    2
    3
    root@root:~$ grep --color "LA" /etc/passwd
    root@root:~$ grep --color -i "LA" /etc/passwd
    gdm:x:121:125:Gnome Display Manager:/var/lib/gdm3:/bin/false
  • grep处理多文件

    • grep可以一次处理多个文件,最长使用的一个场景是:从大量文件中找出含有特定字符的文件.
    • grep -l “query key word” *.txt从多个文件中查找含有被查询的关键词的文件有哪些,应该得到一个文件列表
    • grep -L “query key word” .txt反向选项,从多个文件中查找*不包含**被查询的关键词的文件有哪些,应该得到一个文件列表
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # 当前目录下有三个文件
    [roc@roclinux ~]$ ll
    total 12
    -rw-rw-r-- 1 roc roc 58 Mar 15 17:47 1.txt
    -rw-rw-r-- 1 roc roc 59 Mar 15 17:51 2.txt
    -rw-rw-r-- 1 roc roc 58 Mar 15 17:52 3.txt

    # 1.txt文件的内容如下
    [roc@roclinux ~]$ cat 1.txt
    this first file
    this file contain some import infomation.

    # 2.txt文件的内容如下
    [roc@roclinux ~]$ cat 2.txt
    this second file
    this file contain some import infomation.

    # 3.txt文件的内容如下
    [roc@roclinux ~]$ cat 3.txt
    this third file
    this file contain some import infomation.
    1
    2
    3
    # 使用-l选项
    [roc@roclinux ~]$ grep -l "first" *.txt
    1.txt
    1
    2
    3
    [roc@roclinux ~]$ grep -L "first" *.txt
    2.txt
    3.txt
  • grep支持正则表达式

    ^sp表示以sp开头的行;se$表示以se结尾的行.

    1
    2
    3
    4
    root@root:~$ grep '^sp' -c /etc/passwd
    1
    root@root:~$ grep 'sp' -c /etc/passwd
    5
    1
    2
    3
    4
    root@root:~$ grep 'se' -c /etc/passwd
    7
    root@root:~$ grep 'se$' -c /etc/passwd
    5
  • grep查询一个词

    如要搜索含有bin这个词的行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    root@root:~$ grep '\<bin\>' /etc/passwd --color
    root:x:0:0:root:/root:/bin/bash
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    sync:x:4:65534:sync:/bin:/bin/sync
    proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
    speech-dispatcher:x:111:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/false
    whoopsie:x:112:117::/nonexistent:/bin/false
    hplip:x:118:7:HPLIP system user,,,:/var/run/hplip:/bin/false
    gnome-initial-setup:x:120:65534::/run/gnome-initial-setup/:/bin/false
    gdm:x:121:125:Gnome Display Manager:/var/lib/gdm3:/bin/false
    root:x:1000:1000:root,,,:/home/root:/bin/bash

    这样的词有一个问题,那就是连sbin这样的词也会被搜索出来.因此,我们需要理解词的定义,以及正则表达式中如何表示一个词.
    首先,正则表达式中的词(word),一般是由字母,数字和下划线组成,且词和词之间通常使用空格,制表符或换行符分隔.举个’栗子’,“I love you.”中的“love”就是一个“词”,但“My gloves are red.”中的“love”就不能称作一个“词”。
    在正则表达式中,通常用尖括号表示一个词,比如能够匹配I love you.但不能匹配My gloves are red.

正则表达式

awk

awk命令是一个非常棒的数据处理工具.sed命令一次处理一整行,awk命令一次处理一整行,但将每行的内容分成多个字段来处理.

uniq

sort

sort对文本进行排序。可以按照字典顺序进行排序,或者按照数字排序或者按照特定列排序。sort默认按照字典序进行排序。和sed命令类似,sort命令不会修改原文件。

  • sort -n:按数值来进行比较,只会傻傻地比较数字,他会认为98K大于2G。
  • sort -h:先比较单位,然后比较数值。
  • sort -u:去除重复行
  • sort -t:指定分隔符,未指定时,默认分隔符为空白
  • sort -k指定列排序
  • sort -o:如果需要将排序结果保存到文件中,需要使用-o选项
  • sort -c:用来检查文本内容是否已经是排好序的
  • sort -m:合并已经排好序的文本,但不会重新排序

例子

xargs

xargs是execute argument的缩写,它的作用是从标准输入中读取内容,并将此内容传递给它要协助的命令,并作为那个命令的参数来执行

cat命令可以接收文件名作为参数,执行后会显示出文件的内容。但是cat命令不能直接从标准输入接收参数。 管道可以实现:将前面的标准输出作为后面的“标准输入”;管道无法实现:将前面的标准输出作为后面的“命令参数”。
xargs可以实现:将标准输入(前一个命令的标准输出)作为其指定命令的参数。 xargs 的标准输入中出现的“换行符、空格、制表符”都将被空格取代。

一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#我们创建了3个日志文件, 且故意让文件名称中都含有空格
[xixi2@xixi2 ~]$ for((i=0;i<3;i++)); do touch "test ${i}.log";done

[xixi2@xixi2 ~]$ ls -F
test 0.log test 1.log test 2.log


# 首先使用find命令找出这三个文件
[xixi2@xixi2 ~]$ find -name '*.log' -print
./test 0.log
./test 2.log
./test 1.log

# 使用xargs命令删除这三个文件,出现错误
[xixi2@xixi2 ~]$ find . -name '*.log' -print | xargs rm
rm: 无法删除'./test': 没有那个文件或目录
rm: 无法删除'0.log': 没有那个文件或目录
rm: 无法删除'./test': 没有那个文件或目录
rm: 无法删除'2.log': 没有那个文件或目录
rm: 无法删除'./test': 没有那个文件或目录
rm: 无法删除'1.log': 没有那个文件或目录

# 使用xargs命令删除这三个文件,正确删除
[xixi2@xixi2 ~]$ find . -name '*.log' -print0 | xargs -0 rm -f

当 find 命令获取到的文件名经过 xargs 传送给 rm 命令时,文件“./test 1.log”就变成了“./test”和“1.log”两个文件了。即原本 3 个文件名刹那间就变成了 6 个文件名,而这 6 个文件其实并不存在,从而引发了错误。
xargs -0选项可以将分隔符从默认的空格变成NULL,还会将单引号、双引号、反斜线等统统看作是普通字符。所以说,-0选项特别适合处理命令参数中含有引号、空格、反斜线的情况。
xargs -d选项可以用来指定任何一个符合作为分隔符。
xargs -p选项可以让我们在命令执行过程中进行确认。如果在前一个命令的标准输出中,会有一些参数是你不希望或者不确定是否要传送给后面命令的,这个时候我们就希望 xargs 在传送参数前和我们确认一下。但是此时对所有的参数仅询问一次。如果再加上-n选项可以逐个确认。
xargs -E当碰到某个特定的命令参数时,要求xargs立即终止并退出。

xargs可以处理参数列表过长的问题。借助xargs,并利用管道的特性。将前一个命令的标准输出分段传给后一个xargs,然后作为其指定命令的参数。
例子:创建10万个日志文件,并且用rm命令一次性删除。

1
2
3
4
5
6
# 创建10万个日志文件
[xixi2@xixi2 ~]$ for((i=0;i<100000;i++)); do touch test${i}.log; done

# 用rm命令删除文件
[xixi2@xixi2 ~]$ rm $(find . -type f -name '(.log')
bash: /bin/rm: 参数列表过长

参数列表过长,说明rm可接受的参数长度达到了极限。系统限制了参数的长度。可以通过下面的命令查看系统的参数长度限制值。

1
2
[xixi2@xixi2 ~]$  getconf ARG_MAX
2097152

当遇到参数过长的问题,解决方法有多种。比如说手工分组以缩短参数的长度。但是这个方法并不优雅,而且费时费力。最优雅的方法当然是借助xargs。

1
[xixi2@xixi2 ~]$ find . -type f -name '*.log' | xargs rm

cut

cut负责在文件中剪切数据。cut是以每一行作为一个处理对象。

  • cut的定位依据
    • cut有三类定位方法
      • 按字节(bytes)定位(字节从1开始计算),用-b选项
      • 按字符(characters)定位,用-c选项
      • 按域(field)定位,用-f选项
    • 字节定位的技巧
      • -b选项支持3-5这样的写法,而且多个定位数字之间还可以用逗号隔开
      • -b选项定位时会将所有的定位数字按照从小到大的顺序排序,然后再依次提取。可以随意颠倒定位数字的顺序
    • 定位数字的设置
      • 只限定最大定位数或最小定位数
  • cut -d自定义分隔符,默认为制表符;cut只允许分隔符是一个字符.因此,我们知道cut不善于处理”多空格分隔”的情况.

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看文件aa.txt的内容
[xixi2@xixi2 ~]$ cat aa.txt
good day nice to meet you

# 查看文件aa.txt的信息
[xixi2@xixi2 ~]$ ls -l aa.txt
-rw-r--r-- 1 xixi2 xixi2 26 9月 28 16:58 aa.txt

[xixi2@xixi2 ~]$ echo "good day nice to meet you" | cut -b 1
g

[xixi2@xixi2 ~]$ echo "good day nice to meet you" | cut -b 1-4,6-8
goodday

# 范围1-4和6-8可以颠倒着写,但是1和4(6和8)不能颠倒
[xixi2@xixi2 ~]$ echo "good day nice to meet you" | cut -b 6-8,1-4
goodday

定位数字的设置,只限定最大定位数或最小定位数

1
2
3
4
5
6
7
8
9
10
11
# -3表示从头到第3个字节,包括第3个字符
[xixi2@xixi2 ~]$echo "good day nice to meet you" | cut -b -3
goo

# 3-表示从第三个字节到行尾,包括第3个字符
[xixi2@xixi2 ~]$echo "good day nice to meet you" | cut -b 3-
goo

# 没有同时出现两个第3个字符o,只出现了一个
[xixi2@xixi2 ~]$ echo "good day nice to meet you" | cut -b -3,3-
good day nice to meet you

cut -f按字段进行分割
cut -d可以设置分隔符,但是只能设置一个字符。cut只允许分隔符是一个字符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[xixi2@xixi2 ~]$ cut -f 3 aa.txt 
good day nice to meet you

# 以空格为分割符,取其中的第3个字段
# -d选项设置分隔符,且只能设置为1个空格,cut只允许分隔符是一个字符
[xixi2@xixi2 ~]$ cut -d ' ' -f 3 aa.txt
nice

# 取第3到第6个字段,包括第6个字段
[xixi2@xixi2 ~]$ cut -d ' ' -f 3-6 aa.txt
nice to meet you

# 取前3个字段,包括第3个字段
[xixi2@xixi2 ~]$ cut -d ' ' -f -3 aa.txt
good day nice

设置其他分隔符

1
2
3
4
5
6
7
8
9
# ac.txt是以:为分隔符的文件
[xixi2@xixi2 ~]$cat ac.txt
aa:bb:cc:dd:ee
ff:ee:hh:ee:jj

# 以:为分隔符,取第4到第6个字段,包括第4个字段
[xixi2@xixi2 ~]$cut -d ':' -f 4- ac.txt
dd:ee
ee:jj

识别空格和制表符

1
2
3
4
5
6
7
8
9
10
11
# 查看文件内容
[xixi2@xixi2 ~]$ cat tab_space.txt
hello world
good daya hi
bad weather ok

# 使用sed命令确认文件内容到底是制表符还是空格
[xixi2@xixi2 ~]$sed -n l tab_space.txt
hello\tworld$
good\tdaya hi$
bad weather\tok$

如果是制表符,就会显示为\t符号;如果是空格,就会原样显示.

ps和cut一起使用时出现的重复现象

1
2
3
4
5
[xixi2@xixi2 ~]$ ps | cat
PID TTY TIME CMD
3622 pts/2 00:00:00 bash
3630 pts/2 00:00:00 ps
3631 pts/2 00:00:00 cat

ps | cut 组合命令会产生两个进程,即ps进程和cat进程.其中ps进程为写进程,cat为读进程.当ps进程执行时,也会列出cat命令对应的进程的信息.

同样的,ps | cut -b 3组合命令也会产生两个进程,即ps进程和cut进程,其中ps进程为写进程,cut进程为读进程.当ps进程执行时,也会列出cut进程的信息,并且将所有进程的信息都通过管道输出给cut进程.

sed

sed是stream editor的缩写,中文称之为“流编辑器”。
sed命令是一个面向行处理的工具,它以行为处理单位,针对每一行进行处理,处理后的结果会输出到标准输出(STDOUT)。sed命令不会对读取的文件作任何贸然的修改,而是将内容都输出到标准输出中。 sed的命令格式:

1
sed [options] [command] file
  • command部分:针对每行的内容所要进行的处理
  • file部分:要处理的文件,如果忽略file参数,则sed会把标准输入作为处理对象。

sed命令是面向行进行处理的,每一次处理一行内容。处理时,sed会把要处理的行存储在缓冲区中,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕(标准输出)。接着处理下一行,这样不断重复,直到文件末尾。这个缓冲区被称为”模式空间”。

sed -n-n选项警告sed命令:除非是明确表明要输出的行,否则不要输出.-n选项经常和p配合使用,其含义就是,输出那些匹配的行.

command

command分为两块:一块是范围设定,一块是动作处理.

  • 范围设定
    • 指定行数
      • 3,5表示第3,4,5行
      • 5,$表示第5行至文件最后一行
    • 模式匹配
      • /^[^Dd]/表示匹配行首不是以d或D开头的行
      • /^[dD]/表示匹配所以以d或D开头的行
  • 动作处理
    • d:表示删除行
    • p:打印该行
    • r:读取指定文件的内容
    • w:写入指定文件
    • a:在下面插入新行新内容

command部分采用/AA/s/BB/CC/g表示匹配到文件中带有AA的行,并且将这些行中所有的BB替换成CC。

options

-a 在当前行下面插入文件
-n读取下一个输入行,用下一个命令处理新的行而不是用第一个命令
-e执行多个sed命令
-f运行脚本
-i编辑文件内容
-i.bak编辑的同时创造.bak的备份
-r使用扩展的正则表达式

命令

i在当前行上面插入文件
c把选定的行改为新的指定的文本
p打印
d删除
r/R读取文件/一行
w另存
s替换
y替换
h拷贝模板块的内容到内存中的缓冲区
H追加模板块的内容到内存中的缓冲区
g获得内存缓冲区的内容,并替代当前模板块中的文本
G获得内存缓冲区的内容,并追加到当前模板块文本的后面
D删除\n之前的内容

替换标记

数字:表明新文本将替换第几处模式匹配的地方
g:表示新文本将会替换所有匹配的文本
\1:子串匹配标记,前面搜索可以用元字符集
&:保留搜索的字符用来替换其他字符

示例

全局文本替换

s只能局部替换,g会全局替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# s表示替换,将apple替换为dog
xixi2@xixi2:~/liunx_prac$ echo "this is an apple" | sed 's/apple/banana/'
this is a banana

# 从文件中读取数据
# 查看apple.txt文件内容
xixi2@xixi2:~/liunx_prac$ cat apple.txt
this is an apple
what do you prefer? an apple or an orange
an apple a day keeps the doctor away
you need to eat more apples

# 把apple替换为banana
# 其中/是定界符,定界符可以更改
xixi2@xixi2:~/liunx_prac$ sed 's/apple/banana/' apple.txt
this is an banana
what do you prefer? an banana or an orange
an banana a day keeps the doctor away
you need to eat more bananas

# 查看banana.txt文件的内容
xixi2@xixi2:~/liunx_prac$ cat banana.txt
what do you prefer? an apple or an orange
an apple a day keeps the doctor away
you need to eat more apples
what do you want? an apple or an orange?

# 将banana.txt文件中的or替换为and
# s只会部分替换
xixi2@xixi2:~/liunx_prac$ sed 's/or/and/' banana.txt
what do you prefer? an apple and an orange
an apple a day keeps the doctand away
you need to eat mande apples
what do you want? an apple and an orange?

# 将banana.txt文件中的or替换为and
# g会全部替换
xixi2@xixi2:~/liunx_prac$ sed 's/or/and/g' banana.txt
what do you prefer? an apple and an andange
an apple a day keeps the doctand away
you need to eat mande apples
what do you want? an apple and an andange?

更改定界符/

1
2
3
4
5
6
7
8
9
10
11
12
13
# 查看apple2.txt的内容
xixi2@xixi2:~/liunx_prac$ cat apple2.txt
apples/bananas/fruits/
good/bad/no/ho/
orange/doctor/fever/
apple/bad/no/hi/

# 使用#作为定界符
xixi2@xixi2:~/liunx_prac$ sed 's#no/# yes!#' apple2.txt
apples/bananas/fruits/
good/bad/ yes!ho/
orange/doctor/fever/
apple/bad/ yes!hi/

按行查找替换

用数字表示行范围,$表示行尾
用文本模式配置过滤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
xixi2@xixi2:~/liunx_prac$ cat apple.txt 
this is an apple
what do you prefer? an apple or an orange
an apple a day keeps the doctor away
you need to eat more apples

# 把第二行的apple替换为banana
xixi2@xixi2:~/liunx_prac$ sed '2s/apple/banana/' apple.txt
this is an apple
what do you prefer? an banana or an orange
an apple a day keeps the doctor away
you need to eat more apples

# 将第二行到最后一行中的apple全部替换为banana
xixi2@xixi2:~/liunx_prac$ sed '2,$s/apple/banana/' apple.txt
this is an apple
what do you prefer? an banana or an orange
an banana a day keeps the doctor away
you need to eat more bananas

删除d

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
xixi2@xixi2:~/liunx_prac$ cat apple.txt 
this is an apple
what do you prefer? an apple or an orange
an apple a day keeps the doctor away
you need to eat more apples
I have to buy some apples.
which color is the apple? blue or red

# 删除第二行的内容
xixi2@xixi2:~/liunx_prac$ sed '2d' apple.txt
this is an apple
an apple a day keeps the doctor away
you need to eat more apples
I have to buy some apples.
which color is the apple? blue or red

# 删除第二行到第四行的内容
xixi2@xixi2:~/liunx_prac$ sed '2,4d' apple.txt
this is an apple
I have to buy some apples.
which color is the apple? blue or red

# or表示查找,匹配了第2(or),3(doctor),4(more),6(color),所以这些行被删除
xixi2@xixi2:~/liunx_prac$ sed '/or/d' apple.txt
this is an apple
I have to buy some apples.

添加行

命令i(insert插入),在当前行前面插入一行
命令a(append追加),在当前行后面添加一行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 在前面添加一行
xixi2@xixi2:~/liunx_prac$ echo "hello world" | sed 'i\nice to meet you'
nice to meet you
hello world

# 在后面添加一行
xixi2@xixi2:~/liunx_prac$ echo "hello world" | sed 'a\nice to meet you'
hello world
nice to meet you

# 在最后一行后面添加内容
xixi2@xixi2:~/liunx_prac$ sed '$a\what dose an apple look like?' apple.txt this is an apple

# 在第二行后面添加内容
xixi2@xixi2:~/liunx_prac$ sed '2a\what dose an orange look like?' apple.txt

# 在第二行和第四行后添加内容
xixi2@xixi2:~/liunx_prac$ sed '2,4a\what dose an orange look like?' apple.txt

修改命令c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 查看fruits.txt的内容
xixi2@xixi2:~/liunx_prac$ cat fruits.txt
this is an apple
an apple a day keeps the doctor away
you need to eat more apples
which color is the apple? blue or red

# 把fruits.txt第四行的内容替换为I want an apple
# 注意这里是反斜杠\
xixi2@xixi2:~/liunx_prac$ sed '4c\I want an apple' fruits.txt
this is an apple
an apple a day keeps the doctor away
you need to eat more apples
I want an apple

# 把第二行到第四行的内容修改为I want an apple
# 注意替换和修改的区别,第二行到第四行的内容都没有了,并且本来有3行,修改后只有一行了。
xixi2@xixi2:~/liunx_prac$ sed '2,$c\I want an apple' fruits.txt
this is an apple
I want an apple

-i选项修改原文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
xixi2@xixi2:~/liunx_prac$ cat fruit.txt 
this is an apple
an apple a day keeps the doctor away
you need to eat more apples
which color is the apple? blue or red

# 修改fruit.txt第三行的内容并将修改写入原文件
xixi2@xixi2:~/liunx_prac$ sed -i '3c\do you hava a banana?' fruit.txt

# 重新查看原文件内容,发现原文件发生了变化
xixi2@xixi2:~/liunx_prac$ cat fruit.txt
this is an apple
an apple a day keeps the doctor away
do you hava a banana?
which color is the apple? blue or red

# sed -i s命令使用场景:修改服务器配置文件
xixi2@xixi2:~/liunx_prac$ sed -i 's/or/test/' fruit.txt
xixi2@xixi2:~/liunx_prac$ cat fruit.txt
this is an apple
an apple a day keeps the docttest away
do you hava a banana?
which coltest is the apple? blue or red

find

linux find命令用来在指定目录下查找文件。任何位于参数之前的字符串都被视为欲查找的目录名。如果使用该命令时,不设置任何参数,则find命令将在当前目录下查找子目录与文件。并且将查找到的子目录和文件全部进行显示。

1
find path -option [-print] [-exec -ok command] {} \;
1
find <指定目录> <指定条件> <指定动作>

<指定目录>:所要搜索的目录及其所有子目录。默认为当前目录。
<指定条件>:所要搜索的文件的特征。
<指定动作>:对搜索结果进行特定的处理。
如果什么参数都不加,find默认搜索当前目录及其子目录,并且不过滤任何结果(也就是返回所有文件),将它们全部显示在屏幕上。

-amin n:在过去n分钟内被读取过
-cmin n:在过去n分钟内被修改过
-ctime n:在过去n天内被修改过
-atime n:在过去n天内被读取过
-name name, -iname name:文件名称符合name的文件。iname会忽略大小写。
-size n:文件大小是n单位,b代表512位元祖的区块,c表示字元数,k表示kilo bytes,w是一个二个位元组。
-type c:文件类型是c的文件。
d:目录
c:字型装置文件
b:区块装置文件
p:具名伫列
f:一般文件
l:符号链接
s:socket
-pid n:process id是n的文件
-perm:权限,查找具有指定权限的文件和目录,权限的表示如711,644。
-user:查找属于user指定用户的所有的文件。
-group:查找属于
-print:将搜索结果输出到标准输出。
-ok:查找后执行命令的时候询问是否要执行。
-exec:对搜索的结果指令指定的shell命令,执行的时候不询问用户,直接执行。

格式:-exec 命令 {} ;
在}和\一定要有空格才行;
{}的作用:{}表示命令的参数,即找到的文件;
命令的末尾必须以”;“结束;

-ok选项和-exec选项的作用基本一致,区别在于:”-exec”的命令会直接处理,而不询问;”-ok”的命令 2 在处理前会先询问用户是否这样处理,在得到确认命令后,才会执行。

du

du(disk usage),用来展示磁盘使用量的统计信息.
du的默认单位是KB,即1024bytes。但是du的单位还与其他一些设置相关。

1.如果通过–block-size选项设置了块大小,那么,这会成为du输出信息的单位。
2.如果上一条没满足,且设置了环境变量DU_BLOCK_SIZE,这会成为du输出信息的单位。
3.如果前两条都不满足,且设置了环境变量BLOCK_SIZE,这会成为du输出信息的单位。
3.如果前三条都不满足,且设置了环境变量BLOCKSIZE,这会成为du输出信息的单位。
4.如果前四条的都不满足,且设置了环境变量POSIXLY_CORRECT,则du输出信息的单位是512bytes。
5.如果前五条都不满足,且du的输出信息的单位是1024bytes,即KB。

du和ls在展示文件大小的时候,存在着本质的区别:

  • du展示的是磁盘空间占用量。
  • ls展示的是文件内容的大小(文件内容的大小如何计算)。

一个例子(可以看出du和ls命令的不同)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 有一个文件, 里面只输入了a、b两个英文字母
xixi2@xixi2:~/liunx_prac$ cat a.txt
ab

# 用这个方法, 我们可以把文件里的控制字符也展示出来, 发现除了a、b外还包括了一个结尾符。
xixi2@xixi2:~/liunx_prac$ sed -n l a.txt
ab$

# 用ls来查看大小, 发现展示的是3字节
xixi2@xixi2:~/liunx_prac$ ls -l a.txt
-rw-r--r-- 1 root root 3 9月 28 11:16 a.txt

# 用du来查看大小, 发现竟然展示的是4KB
xixi2@xixi2:~/liunx_prac$ du -h a.txt
4.0K a.txt

文件中有三个字符,两个可见字符ab和一个控制字符$,每个字符1个字节,因此这个文件的内容大小就是3bytes。但是由于一个数据块最多只能存一个文件的限制,所以需要一个数据块来存储这个文件,因此这个文件实际占用的磁盘空间就是4KB。

文件系统进驻磁盘之初,就会将磁盘按固定数据块(block)大小进行分隔切块,通常情况下每一个固定数据块大小会被设定为4096bytes,也就是4KB。
同时,大部分文件系统规定:
1.一个数据块中最多存放一个文件的内容,当没有存满时,剩余的空间不得被其他文件使用。
2.当一个文件的内容较大时,则可以存储到多个数据块中。

当文件中存在空洞时,du命令的结果比ls命令的结果要小。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 有一个文件, 里面只输入了a、b两个英文字母
xixi2@xixi2:~/liunx_prac$ cat b.txt
ab

# 用这个方法, 我们可以把文件里的控制字符也展示出来, 发现除了a、b外还包括了一个结尾符。
xixi2@xixi2:~/liunx_prac$ ls -l b.txt
-rw-r--r-- 1 xixi2 xixi2 3 9月 28 11:32 b.txt

# 在b.txt中,用dd命令创造一个大小为1G的空洞
xixi2@xixi2:~/liunx_prac$ dd if=/dev/zero of =b.txt oflag=append bs=1M seek=1024 count=0
dd: you probably want conv=notrunc with oflag=append
记录了0+0 的读入
记录了0+0 的写出
0 bytes copied, 8.4029e-05 s, 0.0 kB/s

# 看看b.txt文件内容,\000代表空洞
xixi2@xixi2:~/liunx_prac$ sed -n l b.txt | head -n 10
ab$
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\

# 用ls查看,b.txt的文件内容大小为1.0G
xixi2@xixi2:~/liunx_prac$ ls -lh b.txt
-rw-r--r-- 1 xixi2 xixi2 1.0G 9月 28 11:35 b.tx

# 用du查看b.txt占用的磁盘空间,仍然只用了一个数据块4KB
xixi2@xixi2:~/liunx_prac$ du -h b.txt
4.0K b.txt

一个文件中的空洞,并不占用磁盘空间,但是这个空洞本身会被认为是文件内容的一部分,所以ls的值很大,但是du的结果仍然保持。

dd

dd(device driver),它用来读取设备、文件中的内容,并原封不动地复制到指定位置。

dd的选项

  • if=文件名:指定输入文件名或设备名,如果省略”if=文件名”,则表示从标准输入读取。
  • of=文件名:指定输出文件名或者设备名,如果省略”of=文件名”,则表示写到标准输出。
  • bs=N:设置单次读入或单次输出的数据块(block)的大小为N个字节。当然也可以使用ibs和obs选项来分别设置。
  • ibs=N:设置单次读入的数据块大小为N个字节,默认为512字节。
  • obs=N:设置单次输出的数据块大小为N个字节,默认为512字节。
  • count=N:表示总共要复制N个数据块(block)。
  • seek=N:从输出文件开头跳过 N 个块后再开始复制。

实例

1
xixi2@xixi2:~/liunx_prac$ dd if=/dev/sda of=/root/sda.img

这个命令将sda盘备份到指定/root/sda.img中去,其中用到了两个选项:

  • if=文件名:指定输入文件名或设备名,如果省略”if=文件名”,则表示从标准输入读取。
  • of=文件名:指定输出文件名或者设备名,如果省略”of=文件名”,则表示写到标准输出。
1
xixi2@xixi2:~/liunx_prac$ echo "helllo" | dd of=hello.txt

上面这个命令从标准输入中(echo的输出会通过管道符成为dd的标准输入)读入”hello”并写入到hello.txt中,如果不指定of=hello.txt,就会直接打印出来。

1
xixi2@xixi2:~/liunx_prac$ dd if=hello.txt of=hi.txt

上面这个命令会拷贝hello.txt的内容到新文件hi.txt中。

使用 /dev/zero 和 /dev/null 来测试磁盘

  • /dev/null,也叫空设备,小名“无底洞”。任何写入它的数据都会被无情抛弃。
  • /dev/zero,可以产生连续不断的 null 的流(二进制的零流),用于向设备或文件写入 null 数据,一般用它来对设备或文件进行初始化。
    可以通过观察下面两个命令的执行时间,来计算出硬盘的读、写性能:
1
2
3
4
xixi2@xixi2:~/liunx_prac$ time dd if=/dev/zero bs=1024 count=1000000 of=/root/1Gb.file
xixi2@xixi2:~/liunx_prac$ time dd if=/dev/zero bs=2048 count=500000 of=/root/1Gb.file
xixi2@xixi2:~/liunx_prac$ time dd if=/dev/zero bs=4096 count=250000 of=/root/1Gb.file
xixi2@xixi2:~/liunx_prac$ time dd if=/dev/zero bs=8192 count=125000 of=/root/1Gb.file

运行结果:

1
2
3
4
5
6
# 对于time dd if=/dev/zero bs=8192 count=125000 of=/root/1Gb.file
记录了125000+0 的读入
记录了125000+0 的写出
1024000000 bytes (1.0 GB, 977 MiB) copied, 2.11034 s, 485 MB/s
0.06user 0.82system 0:02.11elapsed 42%CPU (0avgtext+0avgdata 2424maxresident)k
0inputs+2000000outputs (0major+87minor)pagefaults 0swaps

利用 /dev/urandom 进行格式化

除了 /dev/null 和 /dev/zero 之外,还有一个很重要的文件,即 /dev/urandom,它是“随机数设备”,它的本领就是可以生成理论意义上的随机数。
如果我们想清除硬盘里的某些机密数据,就可以使用 /dev/urandom 这个随机数生成器来产生随机数据,写到磁盘上,以确保将磁盘原始数据完全覆盖掉。

df

用于显示目前在linux系统上的文件系统的磁盘使用情况统计。

df -h以人类可读的格式输出

date

日期换算:距离1970-01-01这个日期15775天的日期是哪一天?

1
2
date -d "1970-01-01 15775 days"
2013年03月11日 星期一 00:00:00 CST

stat

stat命令用于显示inode的内容。
格式:stat [文件或目录]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 文件1_1_bak.txt是一个符号链接,它指向文件1.txt
xixi2@xixi2:~/liunx_prac$ ls -l 1_1_bak.txt
lrwxrwxrwx 1 xixi2 xixi2 5 10月 8 23:17 1_1_bak.txt -> 1.txt

# 查看文件1.txt的i节点(inode)内容
xixi2@xixi2:~/liunx_prac$ stat 1.txt
文件:1.txt
大小:58 块:8 IO 块:4096 普通文件
设备:805h/2053d Inode:27265977 硬链接:2
权限:(0664/-rw-rw-r--) Uid:( 1000/ xixi2) Gid:( 1000/ xixi2)
最近访问:2019-10-09 17:58:09.590182076 +0800
最近更改:2019-10-09 17:58:03.345970241 +0800
最近改动:2019-10-09 17:58:03.345970241 +0800
创建时间:-

# 查看文件1_1_bak.txt的i节点(inode)内容
xixi2@xixi2:~/liunx_prac$ stat 1_1_bak.txt
文件:1_1_bak.txt -> 1.txt
大小:5 块:0 IO 块:4096 符号链接
设备:805h/2053d Inode:27265972 硬链接:1
权限:(0777/lrwxrwxrwx) Uid:( 1000/ xixi2) Gid:( 1000/ xixi2)
最近访问:2019-10-10 20:54:22.155852935 +0800
最近更改:2019-10-08 23:17:03.850733670 +0800
最近改动:2019-10-09 17:08:13.776647219 +0800
创建时间:-

可以得知,stat不会跟随符号链接。无论是对于普通文件还是符号链接文件,都显示的是文件本身的inode内容。

tree

tree用于以树状图列出目录的内容。执行tree名,它会列出指定目录下的所有文件,包括子目录里的文件。

特殊的设备文件

/dev/null是空设备。所有写向这个文件的输出都将被丢弃,而读这个设备会立刻返回一个文件尾标志。所以在cp命令里可以把它用作复制空文件的源文件。

/dev/zero,可以产生连续不断的 null 的流(二进制的零流),用于向设备或文件写入 null 数据,一般用它来对设备或文件进行初始化。

除了 /dev/null 和 /dev/zero 之外,还有一个很重要的文件,即 /dev/urandom,它是“随机数设备”,它的本领就是可以生成理论意义上的随机数。

真实案例

  1. 如何将父目录中的所有文件,不包括子文件夹拷贝到某个子目录中

参考文献

[1]grep: http://c.biancheng.net/linux/grep.html
[2]find: http://c.biancheng.net/view/779.html
[3]find: https://www.runoob.com/linux/linux-comm-find.html
[4]图解linux最常用命令: https://mp.weixin.qq.com/s/Sq6OZyr2LgseUdOZROzoZg
[5]tree: https://www.runoob.com/linux/linux-comm-tree.html
[6]awk:http://c.biancheng.net/view/4082.html
[7]fdisk:https://www.runoob.com/linux/linux-comm-fdisk.html
[8]sort:https://mp.weixin.qq.com/s/LcO0XF3pzBoX9G3Pa1WKEA
[9]dd命令的选项:https://blog.csdn.net/cupidove/article/details/41379047