首页 > 技术文章 > -linux-文件高级管理

arher 2020-12-11 19:12 原文

一 文件处理三剑客命令初探

三剑客命令我们将在shell编程里深入讲解,此处先学会最基本的使用。

1 sed

流式编辑器,主要擅长对文件的编辑操作,我们可以事先定制好编辑文件的指令,然后让sed自动完成对文件的整体编辑。

# 用法
sed 选项 '定位+命令' 文件路径

# 选项
-n	取消默认输出
-r	支持扩展正则元字符
-i  立即编辑文件

# 定位
行定位:
	1定位到第一行
  1,3代表第1行带第3行
  不写定位代表定位所有行
  
正则表达式定位:
	/egon/包含egon的行
  /^egon/ 以egon开头的行 
  /egon$/以egon结尾的行
  
数字+正则表达式定位:
	'1,8p'代表打印1到8行,
  '1,/egon/p'则代表取从第1行到首次匹配到/egon/的行
  
# 命令
d
p
s///g
命令可以用;号连接多多条,如1d;3d;5d代表删除1,3,5行

# =========================》用法示例:p与d
[root@arther-linux /]# sed '' file.txt 
ssss111111
sss
sss
aaa
aa
222
sss

[root@arther-linux /]# sed -n '' file.txt  # 取消了默认输出 本身是输出操作
[root@arther-linux /]# 

[root@arther-linux /]# sed -n '1,/aa/p' file.txt # 以正则方式匹配输出
ssss111111
sss
sss
aaa

[root@arther-linux /]# sed -n '1,/^aa$/p' file.txt 
ssss111111
sss
sss
aaa
aa

[root@arther-linux /]# sed '1,/aaa/d' file.txt  # 使用默认输出 删除操作
aa
222
sss

[root@arther-linux /]# sed '1d;3d;5d' file.txt 
sss
aaa
222
sss

# =========================》用法示例: s///g
[root@arther-linux /]# cat file.txt 
ssss111111
sss
sss
aaa
aa
222aaa
sss

[root@arther-linux /]# sed 's/sss/xxx/g' file.txt # sss->xxx
xxxs111111
xxx
xxx
aaa
aa
222aaa
xxx

[root@arther-linux /]# sed '/^a/s/aa/xxx/g' file.txt 
ssss111111
sss
sss
xxxa
xxx
222aaa
sss
# 每行以a开头的aa换成xxx

[root@arther-linux /]# sed '6s/aaa/xxx/' file.txt 
ssss111111
sss
sss
aaa
aa
222xxx
sss
# 把第6行的aaa换成xxx

[root@arther-linux /]# sed '4,6s/aaa/xxx/g' file.txt 
ssss111111
sss
sss
xxx
aa
222xxx
sss
# 4,6行的aaa换成xxx

[root@arther-linux /]# cat file.txt | sed '2,7d' # sed也支持管道
ssss111111

# 加上-i选项,直接修改文件,通常会在调试完毕确保没有问题后再加-i选项

2 awk

awk主要用于处理有格式的文本,例如/etc/passwd这种

# 用法
awk 选项 'pattern{action}' 文件路径

# 选项
-F 指定行分隔符

# 工作流程 
awk -F: '{print $1,$3}' /etc/passwd

-1.awk会读取文件的一行内容然后赋值给$0
-2.然后awk会以-F指定的分隔符将该行切分成n段,最多可以达到100段,第一段给$1,第二段给$2,依次类推
-3.print输出该行的第一段和第三段,逗号代表输出分隔符,默认与-F保持一致
-4.重复步骤1,2,3直到文件内容读完

# 内置变量
$0 一整行内容 
NR 记录号,等同于行号 
NF 以-F分隔符分隔的段数

# pattern可以是 
/正则/
	/正则/ 	# 该行内容匹配成功正则 
  $1 ~ /正则/ # 第一段内容匹配成功正则 
  $1 !~ /正则/ # 第一段内容没有匹配成功正则 
  比较运算: 
  NR >= 3 && NR <=5 # 3到5行 
  $1 == "root" # 第一段内容等于root
  
# action可以是 
print $1,$3

# 用法示例
[root@arther-linux /]# cat a.txt
root:x:0:0:root:/root:/bin/bash 
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin 
adm:x:3:4:adm:/var/adm:/sbin/nologin 
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
            
[root@arther-linux /]# awk -F: '/^root/{print $1,$3}' a.txt 
root 0
# 匹配到以root开头的那行后,以:进行切分分成若干段,打印其中第1,3段

[root@localhost ~]# awk -F: '$1 ~ /^d/{print $1,$3}' a.txt 	
#以冒号为分隔符,从第一行开始匹配以字母d开头的行,然后打印第一段和第三段
[root@localhost ~]# awk -F: '$1 !~ /^d/{print $1,$3}' a.txt 	
#以冒号为分隔符,从第一行开始匹配不是以字母d开头的行,然后打印第一段和第三段
[root@localhost ~]# awk -F: 'NR>3{print $1}' a.txt 			
#以冒号为分隔符,匹配所有行号大于3的行,打印第一段
[root@localhost ~]# awk -F: '$1 == "lp"{print $0}' a.txt 		
#以冒号为分隔符,匹配第一段内容为lp的行,并打印该行全部内容
[root@localhost ~]# cat a.txt | awk -F: '{print $1}' 
# awk也支持管道

事实上awk是一门编程语言,可以独立完成很强大的操作,我们将在shell编程中详细介绍

3 grep

grep擅长过滤内容

# 用法 
grep 选项 '正则' 文件路径 

# 选项 
-n, --line-number 在过滤出的每一行前面加上它在文件中的相对行号 
-i, --ignore-case 忽略大小写 
--color 颜色 
-l, --files-with-matches 如果匹配成功,则只将文件名打印出来,失败则不打印 通														常-rl一起用,grep -rl 'root' /etc 
-R, -r, --recursive 递归 

# 示例
	[root@localhost ~]# grep '^root' /etc/passwd	
  #匹配以root开头的行
	[root@localhost ~]# grep -n 'bash$' /etc/passwd	 	
  #匹配以bash结尾的行并显示行号
	[root@localhost ~]# grep -rl 'root' /etc	 
  #匹配/etc下文件内容中包含root的文件名并打印(只打印文件名)
  
# grep也支持管道,我们可以发现三剑客命令都支持管道
	
	[root@localhost ~]# ps aux |grep ssh	
  # 查看系统进行并匹配ssh服务的进程
	[root@localhost ~]# ps aux |grep [s]sh	
  # 查看系统进行并匹配ssh服务的进程,但不匹配grep ssh本身

二 文件管理:文件查找

1 查看命令所属文件

[root@localhost ~]# which ip 
/usr/sbin/ip 
# ps: 一些命令的路径都被配置到了环境变量PATH里 echo $PATH

2 查找文件

find [options] [path...] [expression]

按文件名:

[root@localhost ~]# find /etc -name "ifcfg-eth0" 
[root@localhost ~]# find /etc -iname "ifcfg-eth0" # -i忽略大小写 [root@localhost ~]# find /etc -iname "ifcfg-eth*" # *直接匹配所有

按文件大小:

[root@localhost ~]# find /etc -size +3M # 大于3M 
[root@localhost ~]# find /etc -size 3M 
[root@localhost ~]# find /etc -size -3M 
[root@localhost ~]# find /etc -size +3M -ls # -ls找到的处理动作

指定查找的目录深度:

-maxdepth levels 
[root@localhost ~]# find / -maxdepth 5 -a -name "ifcfg-eth0" 
# -a并且,-o或者, 不加-a,默认就是-a

按文件属主、属组找:

[root@localhost ~]# find /home -user egon # 属主是egon的文件 [root@localhost ~]# find /home -group it # 属组是it组的文件 [root@localhost ~]# find /home -user egon -group it 
[root@localhost ~]# find /home -user egon -a -group it # 同上意思一样 [root@localhost ~]# find /home -user egon -o -group it [root@localhost ~]# find /home -nouser 
# 用户还存在,在/etc/passwd中删除了记录 
[root@localhost ~]# find /home -nogroup 
# 用户还存在,在/etc/group中删除了记录 
[root@localhost ~]# find /home -nouser -o -nogroup

按文件类型:

[root@localhost ~]# find /dev -type f # f普通 
[root@localhost ~]# find /dev -type d # d目录 
[root@localhost ~]# find /dev -type l # l链接 
[root@localhost ~]# find /dev -type b # b块设备 
[root@localhost ~]# find /dev -type c # c字符设备 
[root@localhost ~]# find /dev -type s # s套接字 
[root@localhost ~]# find /dev -type p # p管道文件

根据inode号查找:-inum n

[root@localhost ~]# find / -inum 1811

按文件权限:

[root@localhost ~]# find . -perm 644 -ls 
[root@localhost ~]# find . -perm -644 -ls 
[root@localhost ~]# find . -perm -600 -ls 
[root@localhost ~]# find /sbin -perm -4000 -ls # 包含set uid [root@localhost ~]# find /sbin -perm -2000 -ls # 包含set gid [root@localhost ~]# find /sbin -perm -1000 -ls # 包含sticky

找到后处理的动作:

-print 
-ls 
-delete 
-exec 
-ok 
[root@localhost ~]# find /etc -name "ifcfg*" -print # 必须加引号 [root@localhost ~]# find /etc -name "ifcfg*" -ls 
[root@localhost ~]# find /etc -name "ifcfg*" -exec cp -rvf {} /tmp \; # 非交互,直接进行操作
[root@localhost ~]# find /etc -name "ifcfg*" -ok cp -rvf {} /tmp \; 
# 交互,每一次操作会有一次询问,确定才能操作成功,用于筛选
[root@localhost ~]# find /etc -name "ifcfg*" -exec rm -rf {} \; [root@localhost ~]# find /etc -name "ifcfg*" -delete # 同上

扩展知识:find结合xargs

[root@localhost ~]# find . -name "*.txt" |xargs rm -rf		
#查找当前目录下*.txt格式的文件并进行删除
[root@localhost ~]# find /etc -name "ifcfg*" |xargs -I {} cp -rf {} /var/tmp	
#查找/etc下名称为ifcfg*的文件并拷贝到/var/tmp下,-I选项表示占位符
[root@localhost ~]# find /var/tmp -name "ifcfg*" |xargs -I {} mv {} /usr	
#查找/var/tmp下名称为ifcfg*的文件并将其移动到/usr下
[root@localhost ~]# find /usr/ -name "ifcfg*" |xargs -I {} chmod 666 {}		
#查找/usr/下名称为ifcfg*的文件并将其权限修改为666

三 文件管理:上传与下载

1 下载

wget命令

wget -O 本地路径 远程包链接地址 
# 将远程包下载到本地,-O指定下载到哪里,可以生路-O 本地路径 
# ps:如果wget下载提示无法建立SSL连接,
# 则加上选项--no-check-certificate wget --no-check-certificate -O 
# 本地路径 远程包链接地址

curl命令

# curl命令是一个利用URL规则在命令行下工作的文件传输工具。它支持文件的上传和下载,所以是综合传输 工具,但按传统,习惯称curl为下载工具。作为一款强力工具,curl支持包括HTTP、HTTPS、[ftp]等众多 协议,还支持POST、cookies、认证、从指定偏移处下载部分文件、用户代理字符串、限速、文件大小、进 度条等特征。做网页处理流程和数据检索自动化,curl可以祝一臂之力。 
[root@localhost ~]# curl -o 123.png https://www.xxx.com/img/hello.png # ps: 如果遇到下载提示无法简历SSL链接,使用-k选项或者--insecure curl -k -o 123.png https://www.xxx.com/img/hello.png

sz命令

# 系统默认没有该命令,需要下载:yum install lrzsz -y 
# 将服务器上选定的文件下载/发送到本机
[root@localhost ~]# sz bak.tar.gz

2 上传

rz命令

# 系统默认没有该命令,需要下载:yum install lrzsz -y 
# 运行该命令会弹出一个文件选择窗口,从本地选择文件上传到服务器。 
[root@localhost opt]# rz # 如果文件已经存,则上传失败,可以用-E选项解决 [root@localhost opt]# rz -E 
# -E如果目标文件名已经存在,则重命名传入文件。新文件名将添加一 个点和一个数字(0..999)

四 文件管理:输出与重定向

输出即把相关对象通过输出设备(显示器等)显示出来,输出又分正确输出和错误输出一般情况下标准输出设备为显示器,标准输入设备为键盘。

Linux中用

  • 0代表标准输入
  • 1代表标准正确输入
  • 2代表标准错误输出

![image-20201123201030101](/Users/arther_wan/Library/Application Support/typora-user-images/image-20201123201030101.png)

输出重定向:

正常输出是把内容输出到显示器上,而输出重定向是把内容输出到文件中,>代表覆盖原文件,>>代表在原文件中追加

ps:标准输出的1可以省略

![image-20201123201346662](/Users/arther_wan/Library/Application Support/typora-user-images/image-20201123201346662.png)

例如:ifconfig > test.log 即把ifconfig执行显示的正确内容写入test.log.当前页面不再显示执行结果。

注意:错误输出重定向>与>>后边不要加空格

![image-20201123201645109](/Users/arther_wan/Library/Application Support/typora-user-images/image-20201123201645109.png)

注意:

  • 下述两个命令作用相同

    命令 >>file.log 2>&1 
    命令 &>>file.log
    
  • 正确日志和错误日志分开保存

    命令 >>file1.log 2>>file2.log
    
    [root@arther-linux test]# echo "info" &>>file1.log 2>>file2.log
    [root@arther-linux test]# cat file1.log 
    info
    [root@arther-linux test]# cat file2.log
    [root@arther-linux test]# 
    
  • 系统有个常见用法 ls &>/dev/null 正确输出或错误输出结果都不要。(null可以理解为黑洞或垃圾站)

输入重定向:

# 没有改变输入的方向,默认键盘,此时等待输入
No
no

#没有改变输入的方向,默认键盘,此时等待输入 [root@egon ~]# grep 'root' oldboy root root
echo "hello cm qq:123456" >> file.txt
[root@cm ~]# tr 'cm' 'CM' < file.txt	
#从file.txt文件中读取内容,将小写cm替换为大写CM

[root@cm ~]# grep 'root' < /etc/passwd	
#从/etc/passwd文件中读取内容匹配root所在的行
root:x:0:0:root:/root:/bin/bash

# mysql如何恢复备份,了解即可,不用关注。	#将bbs.sql中读取到的内容恢复到MySQL中。
[root@qls ~]# mysql -uroot -p123 < bbs.sql

五 文件管理:字符处理命令

1 sort命令

用于将文件内容加以排序

  • -n 按照数值的大小排序
  • -r 以相反的顺序来排序
  • -k 以某列进行排序
  • -t 指定分隔符,默认是以空格为分隔符

准备文件,写入一段无序的内容

[root@arther-linux test]# cat >> file.txt <<EOF
> b:3
> c:2
> a:4
> e:5
> d:1
> f:11
> EOF
#将终端输入内容插入file.txt文件中,碰到字符EOF结束。

[root@arther-linux test]# sort file.txt 
a:4
b:3
c:2
d:1
e:5
f:11
# 此时已每行的首字母排序

[root@arther-linux test]# sort -t ':' -n -k2 file.txt
d:1
c:2
b:3
a:4
e:5
f:11
# 以冒号为间隔符,对数字类型做比较,比较第二个字段的值

[root@arther-linux test]# sort -t ':' -n -r -k2 file.txt
f:11
e:5
a:4
b:3
c:2
d:1
# 在上一个基础上进行倒叙排序

2 uniq命令

用于检查及删除文本文件中重复出现的行列,一般与sort命令结合使用

  • -c 在每列旁边显示该行重复出现的次数
  • -d 仅显示重复出现的行列
  • -u 仅显示出现一次的行列(排除重复出现的,及原数据)

准备文件,写入一段无序的内容

[root@arther-linux test]# cat > file.txt <<EOF   # > 指覆盖原文件操作
> hello
> 123
> hello
> 123
> func
> EOF

[root@arther-linux test]# file.txt | uniq
bash: file.txt: 未找到命令...
[root@arther-linux test]# sort file.txt | uniq
123
func
hello
# 所以需要与sort连用,去掉重复的内容

[root@arther-linux test]# sort file.txt | uniq -c
2 123
1 func
2 hello
# 去掉重复的内容并统计出现的次数

[root@arther-linux test]# sort file.txt | uniq -d
123
hello
# 只显示重复了内容

[root@arther-linux test]# sort file.txt | uniq -u
func
# 只显示出现了一次的内容

3 cut命令

cut命令用来显示行中的指定部分,删除文件中指定字段

  • -d 指定字段的分隔符,默认的字段的分隔符为"TAB"
  • -f 显示指定字段的内容
[root@arther-linux /]# head -1 /1.txt 
t:x:0:0:root:/root:/bin/bash   # 获取第一行数据

[root@arther-linux /]# head -1 /1.txt | cut -d ":" -f1,3,5
t:0:root   # 以":"切分之后获取第1,3,5段的内容
    

4 tr命令

替换或删除命令

  • -d 删除命令

例1

[root@arther-linux /]# head -1 /1.txt | tr "root" "ROOT"
T:x:0:0:ROOT:/ROOT:/bin/bash
# 替换:root->ROOT

[root@arther-linux /]# head -1 /1.txt | tr -d "root"
:x:0:0::/:/bin/bash
# 该段的字符删除

例2

[root@arther-linux /]# echo "hello arther qq:1813142161" > file.txt 
[root@arther-linux /]# tr "arther" "ARTHER" < file.txt 
HEllo ARTHER qq:1813142161
  
[root@arther-linux /]# cat file.txt | tr "arther" "ARTHER"
HEllo ARTHER qq:1813142161

5 wc命令

统计,计算数字

  • -c 统计文件的Bytes数
  • -l 统计文件的行数
  • -w 统计文件中单词的个数,默认以空白字符做为分隔符

例1

[root@arther-linux /]# ll file.txt 
-rw-r--r--. 1 root root 27 11月 23 20:57 file.txt
[root@arther-linux /]# wc -c file.txt 
27 file.txt

例2

[root@arther-linux /]# wc -l 2.txt 
28 2.txt
# 显示总共出现多少行

[root@arther-linux /]# grep "ssa" 2.txt |wc -l
16
# 该字符在文件中出现的次数

[root@arther-linux /]# wc -w 2.txt
160 2.txt
# 出现了多少个单词,默认以空格为分隔符,来判定单词的数量

六 文件管理:打包压缩

1 什么是打包压缩

​ 打包指的是将多个文件和目录合并为一个特殊文件

​ 然后将该特殊文件进行压缩

​ 最终得到一个压缩包

2 为什么使用压缩包

​ 减少占用的体积

​ 加快网络的传输

3 Windows的压缩和Linux的有什么不同

​ windows: .zip .rar(linux不支持)

​ linux: .zip tar.gz tar.bz2 .gz .bz2

​ 如果希望windows的软件能被linux解压,或者linux的软件包被windows能识别,选择zip.

PS: 压缩包的后缀不重要,但一定要携带.

4 linux下常见的压缩包类型

格式 压缩工具
.zip zip压缩工具
.gz gzip压缩工具,只能压缩文件,会删除原文件(通常配合tar使用)
.bz2 bzip2压缩工具,只能压缩文件,会删除原文件(通常配合tar使用)
.tar.gz 先使用tar命令归档打包,然后使用gzip压缩
.tar.bz2 先使用tar命令归档打包,然后使用bzip压缩

ps:windows下支持.rar,linux不支持.rar

5 打包压缩的方法

方法一:

# 1、打包 
[root@localhost test]# tar cvf etc_bak.tar /etc/ # c创建 v详细 f打包后文件路径 
ps: 
  打包的目标路径如果是绝对路径,会提示:tar: 从成员名中删除开头的“/”,不影响打包, 	 添加-P选项便不再提示:tar cvPf ...
  可以cd 到 /etc下然后tar cvf etc_bak.tar *打包,这样去掉了一层文件夹
  
# 2、压缩 
[root@localhost test]# gzip etc_bak.tar # 文件体积变小,并且加上后缀.gz 
ps: 
  gzip -> gunzip 
  bzip2-> bunzip2
  
#3、上述两步可以合二为一
[root@localhost test]# tar czvf etc1_bak.tar.gz /etc/  
# 选项z代表gzip压缩算法
[root@localhost test]# tar cjvf etc1_bak.tar.bz2 /etc/  
# 选项j代表bzip2压缩算法
	
	解压命令:无论哪种压缩格式解压命令都相同
	tar xvf etc1_bak.tar.gz -C /usr/local/		
  #将etc1_bak.tar.gz压缩包解压到/usr/local下
	tar xvf etc1_bak.tar.bz2  .					
  #将etc1_bak.tar.bz2压缩包解压到当前目录下

方法二:

#zip压缩 
选项:
		-r #递归压缩 压缩目录 
  	-q #静默输出 
# 示例1、 
[root@localhost ~]# zip /test/bak.zip a.txt b.txt c.txt 
# zip后的第一个参数是压缩包 路径,其余为被压缩的文件 
adding: a.txt (stored 0%) 
adding: b.txt (stored 0%) 
adding: c.txt (stored 0%) 
  
[root@localhost ~]# ls /test/ bak.zip 
  
# 示例1、 
[root@localhost ~]# zip -rq etc.zip /etc # 加上-q后压缩过程不再提示

6 解压缩

#1、针对xxx.tar.gz 或者 xxx.tar.bz2,统一使用 
[root@localhost test]# tar xvf 压缩包 -C 解压到的目录 # 无需指定解压算法,tar会自动判断 

#2、针对xxx.zip,用unzip 
选项:
		-l #显示压缩包的列表信息 
  	-q #静默输出 
    -d #解压到指定的目录 
[root@localhost test]# unzip -q xxx.zip -d /opt

推荐阅读