推荐个linux命令的项目:https://github.com/jaywcjlove/linux-command
可通过在https://unpkg.com/linux-command/command/命令名.md中替换命令名查看指定命令信息。
shell命令可以使用
man
查看命令文档说明,说明界面中可通过b
(backward)向上翻页,f
(forward)向下翻页,g
(go to)跳到说明首页,G
跳到说明尾页,/
+搜索字符搜索指定内容。
官方文档:https://www.gnu.org/software/coreutils/manual/html_node/
1.date
处理日期时间相关的命令,主要用到的参数-d
,根据-d的参数值获取指定的日期时间,省略该参数获取当前日期时间。
map@gzdt-map-poi-yingxiang-offline04 coordinate$ date +%Y%m%d
20240703
map@gzdt-map-poi-yingxiang-offline04 coordinate$ date -d 'last day' +%Y%m%d
20240702
map@gzdt-map-poi-yingxiang-offline04 coordinate$ date -d '-1 day' +%Y%m%d
20240702
map@gzdt-map-poi-yingxiang-offline04 coordinate$ date -d '-1 days' +%Y%m%d
20240702
map@gzdt-map-poi-yingxiang-offline04 coordinate$ date -d '+1 day' +%Y%m%d
20240704
map@gzdt-map-poi-yingxiang-offline04 coordinate$ date -d 'sunday' +%Y%m%d
20240707
map@gzdt-map-poi-yingxiang-offline04 coordinate$ date -d 'last sunday' +%Y%m%d
20240630
map@gzdt-map-poi-yingxiang-offline04 coordinate$ date -d 'last sunday -1 week' +%Y%m%d
20240623
格式化字符串中常用:
%Y:year
%m:month (01…12)
%d:day of month (01…31)
%H:hour (00…23)
%M:minute (00…59)
%S:second (00…60)
2.du(disk use)
查看目录的磁盘占用大小。
du -h --max-depth=1 ./
或者 du -h -d 1 ./
:查看当前路径下各目录及文件的大小,对于目录是递归累计大小的。不指定路径默认为当前所在目录。--max-depth=1
& -d 1
,一个长参数形式一个短参数形式,都是用来指定控制台输出时只输出顶层目录文件,不递归输出。
3.df(disk free)
也是用来查看磁盘使用情况的,和du
不同的是,关注的是磁盘和挂载点目录的使用情况(包括总大小和已使用),而非某个具体目录。
所以df -h
无论在哪个路径执行默认都是输出所有磁盘或磁盘分区及对应挂载点&挂载点目录的使用情况,如果指定目录路径,则会输出该目录路径所在挂载点的磁盘使用情况。
map@gzdt-map-poi-yingxiang-offline04 disk1$ df -h
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 126G 0 126G 0% /dev
tmpfs 126G 11M 126G 1% /dev/shm
tmpfs 126G 1.1G 125G 1% /run
tmpfs 126G 0 126G 0% /sys/fs/cgroup
/dev/sda2 19G 11G 6.6G 63% /
/dev/nvme1n1 917G 512M 917G 1% /ssd2
/dev/nvme0n1 917G 26G 892G 3% /ssd1
/dev/sda1 952M 9.9M 942M 2% /boot/efi
/dev/sda6 1.9G 425M 1.4G 24% /has
/dev/sda5 4.6G 765M 3.7G 18% /matrix
/dev/sda3 14G 1.4G 12G 11% /var
/dev/sda4 14G 1.7G 12G 13% /noah
/dev/sda8 3.6T 3.1T 518G 86% /home
/dev/sdc1 3.6T 3.2T 480G 87% /home/disk2
/dev/sdb1 3.6T 1.1T 2.6T 30% /home/disk1
/dev/sdd1 3.6T 3.4T 215G 95% /home/disk3
/dev/sde1 3.6T 3.4T 267G 93% /home/disk4
/dev/sda7 6.5G 4.6G 1.5G 76% /tmp
none 800M 152M 649M 19% /noah/download
none 800M 597M 204M 75% /noah/modules
none 400M 128K 400M 1% /noah/tmp
none 100M 0 100M 0% /noah/bin
tmpfs 26G 0 26G 0% /run/user/1006
tmpfs 26G 0 26G 0% /run/user/0
afs_mount 96P 68P 28P 71% /home/dfs/map_data_aoi
map@gzdt-map-poi-yingxiang-offline04 disk1$ df -h /home/disk1/map/
文件系统 容量 已用 可用 已用% 挂载点
/dev/sdb1 3.6T 1.1T 2.6T 30% /home/disk1
挂载点:可以理解为物理磁盘或物理磁盘的某个分区在文件系统中的入口,通过挂载点入口目录管理物理磁盘或分区中的内容。
4.find
find命令可以用来查找机器上的文件,一种比较常用的查找方式为find / -name "*filename*" 2>/dev/null
,表示从根路径下查找文件名包含filename的文件,后面的 2>/dev/null 表示忽略权限错误输出。
这个命令特别需要注意下传递给-name参数的值*filename*
,加引号和不加引号的区别:
- 加引号:则
*filename*
这个字符串会作为整体传递给name参数,由find命令来解释特殊字符*
的含义,表示从指定路径下搜索所有包含filename的文件或文件夹,和搜索预期一致。- 不加引号:会先对
*filename*
中特殊含义的字符如*
在命令执行路径下(非查找路径) 下进行拓展,查找该路径下是否存在可以匹配*filename*
的文件,存在时就将第一个可以匹配的文件名传递给name,此时相当于按照第一个可以匹配的文件名精确查找了。不存在匹配结果时会和不加引号时一样将原字符串作为整体传递给name,此时加不加引号对于结果没影响。
引号测试:
map@gzdt-map-poi-yingxiang-offline04 test$ tree dir1
dir1
├── dir2
│ └── file2
└── file1
1 directory, 2 files
# dir1下模糊查找所有包含 file 的文件文件夹
map@gzdt-map-poi-yingxiang-offline04 dir1$ find ./ -name "*file*"
./dir2/file2
./file1
# dir1路径下file1匹配,所以实际查找效果相当于:find ./ -name file1
map@gzdt-map-poi-yingxiang-offline04 dir1$ find ./ -name *file*
./file1
# 当命令执行路径下不存在匹配文件时,效果等同于加引号
map@gzdt-map-poi-yingxiang-offline04 dir1$ ll .. | grep file
map@gzdt-map-poi-yingxiang-offline04 dir1$ cd .. && find ./ -name *file*
./dir1/dir2/file2
./dir1/file1
如果文件名较复杂,也可以通过-regex
进行正则查找:
在find种正则查找时是全路径匹配,也就是当查找某个文件时,给出的正则必须要能满足对该文件的全路径进行匹配,而不是仅匹配文件名。
map@gzdt-map-poi-yingxiang-offline04 dir1$ find ./ -regex "file.*"
map@gzdt-map-poi-yingxiang-offline04 dir1$ find ./ -regex ".*file.*"
./dir2/file2
./file1
5.crontab
该命令用来做定时任务。默认每个用户在/var/spool/
路径下都拥有一个和自己同名的crontab文件,通过编辑该文件进行任务的设置。
使用提供的crontab命令打开文件编辑,而非直接编辑。编辑完成后和vim编辑器一样
:wq
保存修改,服务会自动重新读取文件中的任务。
相关命令:
systemctl status crond # 查看服务状态
systemctl start crond # 启动服务
systemctl stop crond # 关闭服务
crontab -e # 打开任务文件
crontab -l # 显示当前已有的定时任务
时间配置一般格式都是* * * * * command
这样,前面5个*
的位置用来设置任务执行时间,后面跟上需要执行的命令。
* * * * * command to be executed
- - - - -
| | | | |
| | | | +----- day of week (0 - 6) (Sunday=0)
| | | +------- month (1 - 12)
| | +--------- day of month (1 - 31)
| +----------- hour (0 - 23)
+------------- min (0 - 59)
*
所在的5个位置从前到后分别表示分钟(0~59)、小时(0~23)、日期(1~31)、月份(1~12)、星期(1~6周一~周六;0周日),为*
时表示所有时刻。例如0 0 * * 5
表示每个周五的0点0分开始执行。
还有3个特殊的字符了解一下:
/
、-
、,
。
/
表示per(每个时间单位间隔)的意思
-
指定连续的时间范围
,
指定离散的时间范围
6.netstat
用来查看网络相关信息。常用参数:
-n:以数字形式显示地址和端口号,不将端口号转换为服务名。
-t:仅显示TCP端口。
-u:仅显示UDP端口。
-l:仅显示处于LISTEN状态的端口,即那些正在等待新连接的套接字。
7.sort
排序命令,重点关注下面几个参数:
-r:倒序
-n:按数字大小排序
-k:用于指定排序的列,初始列序号1。两种指定格式,1)n:从第n个字段到最后;2)m, n:仅第m到第n个字段(指定范围的字段相等时,还是会使用默认比较规则,将后续的字段拿来比较。因此,如果想仅使用指定区间的字段比较,可以通过加-s
参数实现)。
-t:指定列分隔符,对于特殊字符如\t
,不能直接写\t
,否则linux会将该字符解释为\
和t
两个字符,需要$'\t'
(注意只能单引号,不能双引号)
-s:指定的比较字段都相等时,不继续往后比较(稳定排序)。
map@gzdt-map-poi-yingxiang-offline04 ext0722$ head -n 5 0722_diff_mt15_v2 | awk 'BEGIN{FS="\t"} {print $8}'
91.58
16.74
32.58
202.04
26.00
map@gzdt-map-poi-yingxiang-offline04 ext0722$ sort -nrk8 -t$'\t' 0722_diff_mt15_v2 | head -n 5 | awk 'BEGIN{FS="\t"} {print $8}'
313950.88
90021.19
90015.74
83918.10
81265.28
map@gzdt-map-poi-yingxiang-offline04 test$ cat sort.date
A B D
A B
A C
map@gzdt-map-poi-yingxiang-offline04 test$ sort -k 1,2 sort.date
A B
A B D
A C
map@gzdt-map-poi-yingxiang-offline04 test$ sort -sk 1,2 sort.date
A B D
A B
A C
8.cut
用于文本处理,常用参数:
-f:提取字段的列号,1开始。(指定多个列时通过
,
分隔,或者-
指定范围)
-d:指定字段分隔符,分隔符必须引号包裹,单双无所谓。默认分隔符\t
。(如果一行数据中不包含分隔符,则-f
参数无论指定几都是输出整行数据)
-s:如果一行数据中不包含分隔符,则不输出整行数据。
--complement:单词“补充”的意思,实际意义为取反,也就是输出除-f
指定字段外的所有字段。
map@gzdt-map-poi-yingxiang-offline04 extract_data$ head -n 3 address_test2
17054641415935739074,购物;购物中心,红日大道与南京路交口(县医院东500米路南)
9014163594456351084,购物;购物中心,青岛市西海岸新区珠江路667号
15053513364187350286,购物;购物中心,菏泽市曹县青菏路与长江路交叉路口往东南约140米
map@gzdt-map-poi-yingxiang-offline04 extract_data$ head -n 3 address_test2 | cut -d "," -f1
17054641415935739074
9014163594456351084
15053513364187350286
map@gzdt-map-poi-yingxiang-offline04 extract_data$ head -n 3 address_test2 | cut -d "," -f1,2-3
17054641415935739074,购物;购物中心,红日大道与南京路交口(县医院东500米路南)
9014163594456351084,购物;购物中心,青岛市西海岸新区珠江路667号
15053513364187350286,购物;购物中心,菏泽市曹县青菏路与长江路交叉路口往东南约140米
map@gzdt-map-poi-yingxiang-offline04 extract_data$ head -n 3 address_test2 | cut -d "," -f1 --complement
购物;购物中心,红日大道与南京路交口(县医院东500米路南)
购物;购物中心,青岛市西海岸新区珠江路667号
购物;购物中心,菏泽市曹县青菏路与长江路交叉路口往东南约140米
map@gzdt-map-poi-yingxiang-offline04 extract_data$ head -n 3 address_test2 | cut -d $'\t' -f1
17054641415935739074,购物;购物中心,红日大道与南京路交口(县医院东500米路南)
9014163594456351084,购物;购物中心,青岛市西海岸新区珠江路667号
15053513364187350286,购物;购物中心,菏泽市曹县青菏路与长江路交叉路口往东南约140米
map@gzdt-map-poi-yingxiang-offline04 extract_data$ head -n 3 address_test2 | cut -d $'\t' -f1 -s
上面最后两个测试\t
分隔符可以不指定,默认就是,显式指定只是为了说明当\t
作为分隔符时的传递方式为$'\t'
,而不能直接'\t'
。这个地方在上面sort命令中也说到过,查了下资料,说的是
在 Bash shell 中,
$'string'
是一种特殊的引用机制,称为 ANSI-C 引用。这种引用机制允许你使用转义序列,比如 \n (新行)、\t (制表符) 或 \v (垂直制表符) 等。这些转义序列在引号内部被认为是字符序列,而不是转义字符。
直白的说就是shell中对于引号包裹的转义字符并不会解释,只会当做普通的字符对待。比如\n
,不会解释为换行,只会理解成\
和n
两个字符。下面通过echo命令验证一下,echo的-e参数允许对特殊字符进行解析和转义。
map@gzdt-map-poi-yingxiang-offline04 extract_data$ echo 'a\nb'
a\nb
map@gzdt-map-poi-yingxiang-offline04 extract_data$ echo -e 'a\nb'
a
b
map@gzdt-map-poi-yingxiang-offline04 extract_data$ echo $'a\nb'
a
b
9.join
用于根据指定的字段对两文件的行进行关联匹配。用来join的两文件join之前必须都按照关联字段排序,正序倒序无所谓但得保持一致,且必须按照字典顺序排序(sort的默认排序方式就是按照字典顺序)。
主要参数:
-1:第一个文件中参与关联的字段序号,起始值1
-2:第二个文件中参与关联的字段序号,起始值1
-j:当两文件关联字段序号相同时可以-j
简写
-i:忽略大小写
-a:同时保存指定文件中不匹配的行,参数值 1 or 2,表示保存第一个文件或第二个文件
-t:指定字段的输入输出分隔符,默认空格符或制表符(可以制表符分隔的一般也可以空格分隔,反之不行。因为制表符等其它空白字符本质上是包含多个空格的特殊字符)
--header:识别两文件首行为字段名,不参与join直接输出
map@gzdt-map-poi-yingxiang-offline04 ext0723$ sort -k1 file2 > file2_sort
map@gzdt-map-poi-yingxiang-offline04 ext0723$ sort -k1 file1 > file1_sort
map@gzdt-map-poi-yingxiang-offline04 ext0723$ cat file1_sort
111 广州市
12 北京市
13 上海市
map@gzdt-map-poi-yingxiang-offline04 ext0723$ cat file2_sort
11 武汉市
12 信阳市
13 重庆市
map@gzdt-map-poi-yingxiang-offline04 ext0723$ join -1 1 -2 1 file1_sort file2_sort
12 北京市 信阳市
13 上海市 重庆市
map@gzdt-map-poi-yingxiang-offline04 ext0723$ join -j1 file1_sort file2_sort
12 北京市 信阳市
13 上海市 重庆市
map@gzdt-map-poi-yingxiang-offline04 ext0723$ join -j1 -a1 file1_sort file2_sort
111 广州市
12 北京市 信阳市
13 上海市 重庆市
10.uniq
去重命令,注意的是该命令只对相邻行之间执行去重,所以去重前需要先sort排序让所有相同值的行相邻。
tips:sort | uniq
时,uniq可以通过sort中的-u
参数替代,等价于sort -u
。
常用参数:
-i:忽略大小写,缺省时默认不忽略。
-f:指定的前n个字段不参与比较。默认是对整行数据比较去重。
-c:去重并同时输出每个唯一值的出现次数。
-d:只输出重复了的行,每组重复的数据只输出一行。
map@gzdt-map-poi-yingxiang-offline04 extract_data$ echo -e '1\tA' > test
map@gzdt-map-poi-yingxiang-offline04 extract_data$ echo -e '2\tB' >> test
map@gzdt-map-poi-yingxiang-offline04 extract_data$ echo -e '3\tC' >> test
map@gzdt-map-poi-yingxiang-offline04 extract_data$ echo -e '4\tA' >> test
map@gzdt-map-poi-yingxiang-offline04 extract_data$ echo -e '5\tA' >> test
map@gzdt-map-poi-yingxiang-offline04 extract_data$ cat test
1 A
2 B
3 C
4 A
5 A
map@gzdt-map-poi-yingxiang-offline04 extract_data$ cut -f2 test | uniq
A
B
C
A
map@gzdt-map-poi-yingxiang-offline04 extract_data$ cut -f2 test | sort | uniq
A
B
C
map@gzdt-map-poi-yingxiang-offline04 extract_data$ cat test | sort -k2 | uniq -f1
1 A
2 B
3 C
map@gzdt-map-poi-yingxiang-offline04 extract_data$ cat test | sort -uk2
1 A
2 B
3 C
map@gzdt-map-poi-yingxiang-offline04 extract_data$ cat test | sort -k2 | uniq -cf1
3 1 A
1 2 B
1 3 C
11.iconv
用于编码转换。主要参数:
-f:原编码
-t:目标编码
-c:转换错误时忽略(丢弃)错误字符
map@gzdt-map-poi-yingxiang-offline04 extract_data$ cat test_encoding
14468789265117264909 阳光100B座1608室简龄拾光 阳光100B座1608室简龄•拾光
map@gzdt-map-poi-yingxiang-offline04 extract_data$ iconv -f utf-8 -t gbk test_encoding > test_encoding_gbk
iconv: 未知 80 处的非法输入序列
map@gzdt-map-poi-yingxiang-offline04 extract_data$ iconv -f utf-8 -t gbk -c test_encoding > test_encoding_gbk
12.xargs
xargs命令可以对输入自定义一些格式化输出,但主要用途还是将读取的输入转换成命令行参数。https://unpkg.com/linux-command@1.19.1/command/xargs.md。下面主要演示作为转换命令行参数使用时的一些例子。
作为转换命令行参数使用时主要两种形式,一种是-a
参数读取文件输入,一种是不加任何参数读取上一个命令的标准输出流。
当时工作中用到的场景是需要把最近半个月的所有挖掘结果备份数据同步到另外一个地方,只同步最新的值。每天的备份文件里无重复值,但是不同天的备份文件可能出现重复值,因为策略每天的挖掘结果都会变化。
思路是将所有备份文件(文件名行如file_bak_20241215
)按照文件名倒序cat合并到一个文件,然后awk去下重就可以了。
比如下面两个文件,file_bak_20241215 & file_bak_20241216
(base) map@gzdt-map-poi-yingxiang-offline04 test$ ll
总用量 40
-rw-rw-r-- 1 map map 650 2024-12-16 14:58:55 afs_merge.sh
-rw-rw-r-- 1 map map 168 2024-12-16 15:21:41 dispatch.sh
-rw-rw-r-- 1 map map 9 2024-12-16 19:54:22 file_bak_20241215
-rw-rw-r-- 1 map map 9 2024-12-16 19:54:43 file_bak_20241216
drwxrwxr-x 2 map map 4096 2024-12-16 14:31:56 logs
drwxrwxr-x 5 map map 4096 2024-08-13 15:05:48 output
-rw-rw-r-- 1 map map 3977 2024-12-16 19:43:57 semantic_label_sync.tar.gz
-rw-rw-r-- 1 map map 1652 2024-12-09 15:14:34 test_jingpin.py
-rw-rw-r-- 1 map map 5879 2024-12-09 14:56:59 test_queue.py
(base) map@gzdt-map-poi-yingxiang-offline04 test$ cat file_bak_20241215
1
11
111
(base) map@gzdt-map-poi-yingxiang-offline04 test$ cat file_bak_20241216
2
22
222
(base) map@gzdt-map-poi-yingxiang-offline04 test$ ls -1 file_bak* | sort -r | xargs cat
2
22
222
1
11
111
先输出 file_bak_20241216 文件,再输出 file_bak_20241215文件。
也可以先将文件名逆序保存到文件,然后读取文件的方式传递参数。
(base) map@gzdt-map-poi-yingxiang-offline04 test$ ls -1 file_bak* | sort -r > file
(base) map@gzdt-map-poi-yingxiang-offline04 test$ cat file
file_bak_20241216
file_bak_20241215
(base) map@gzdt-map-poi-yingxiang-offline04 test$ xargs -a file cat
2
22
222
1
11
111
如果想让每个文件内部的数据也逆序输出,可以后面接tac
命令,相当于每次执行的就是命令 tac xxx
了。
(base) map@gzdt-map-poi-yingxiang-offline04 test$ xargs -a file tac
222
22
2
111
11
1
1)
ls -1
,只列出当前目录中的文件和文件夹名称,每个名称占用一行,而不会显示额外的信息。这样可以非常方便地将文件名列表传递给其他命令进行进一步处理,比如通过管道传递给 xargs 或其他脚本。
2)xargs分隔符默认是空格,同一行空格隔开的字符和不同行的字符,都会解析为单独的一个参数。
13.pgrep
根据用户给出的信息在当前运行进程中查找并列出符合条件的进程ID(PID)。
重点关注下面几个参数:
-f
:使用命令行匹配(默认进程名匹配),也就是拿后面的参数值去匹配启动进程时的命令行,返回匹配的进程ID(传递参数值和命令行可以部分匹配)
-a
:列出匹配的进程和启动进程时完整的命令行
-l
:列出匹配的进程和进程名(类似sh
、java
、nginx
…)
(base) map@gzdt-map-poi-yingxiang-offline04 rdgx1_zld_daily_visit$ pgrep -f set_priority.sh
32699
(base) map@gzdt-map-poi-yingxiang-offline04 rdgx1_zld_daily_visit$ pgrep -fa set_priority.sh
32699 sh set_priority.sh
(base) map@gzdt-map-poi-yingxiang-offline04 rdgx1_zld_daily_visit$ pgrep -fl set_priority.sh
32699 sh
后台启动的进程 nohup xxx &
,在显示完整的命令行时不会显示nohup
和&
,查了一下gpt的解释
14.tar
打包解包,主要关注参数:
-c
:打包
-x
:解包
-z
:使用 Gzip 压缩或解压缩归档(推荐),拓展名通常为.tar.gz
或.tgz
-f
:用于指定要创建、查看或解压缩的压缩包名
-v
:verbose(冗长),输出处理过程中的文件名
-t
:列出压缩包中的文件,但不提取
-C
:解压缩时的起始目录,可以修改解压缩的位置,也可以设置压缩文件的路径。
(base) map@gzdt-map-poi-yingxiang-offline04 zhuangtai$ tree a
a
└── b
├── file1
└── file2
1 directory, 2 files
(base) map@gzdt-map-poi-yingxiang-offline04 zhuangtai$ tar -zcf a1.tar.gz ./a/b/
(base) map@gzdt-map-poi-yingxiang-offline04 zhuangtai$ tar -tf a1.tar.gz
./a/b/
./a/b/file2
./a/b/file1
(base) map@gzdt-map-poi-yingxiang-offline04 zhuangtai$ tar -zcf a2.tar.gz -C ./a/b/ ./
(base) map@gzdt-map-poi-yingxiang-offline04 zhuangtai$ tar -tf a2.tar.gz
./
./file2
./file1
(base) map@gzdt-map-poi-yingxiang-offline04 zhuangtai$ tar -zxf a2.tar.gz -C ./a ./
(base) map@gzdt-map-poi-yingxiang-offline04 zhuangtai$ tree a
a
├── b
│ ├── file1
│ └── file2
├── file1
└── file2
1 directory, 4 files
可以看到tar命令打包时,如果待打包的文件类似于a/b/xxx
形式指定,会将目录层级也给打包进去(实际业务中这个问题导致过例行任务报错排查了好久原因!),可以通过-C
参数指定起始目录规避这个问题,或者切换到需要的层级下去打包。