分享生活,记录成长
表达自我,拥抱世界

Linux云计算系统学习第七天

linux高效文件处理三剑客

命令简介:

​ grep 过滤筛选信息
​ sed 修改替换文件内容、对文件中的行进行操作
​ awk 擅长统级分析文件内容、对文件中的列进行操作

grep命令操作详解:

​ grep常用参数:

  -v              取反
  -i              忽略大小写
  -c              符合条件的行数
  -n              输出的同时打印行号
  ^*              以*开头     
  *$              以*结尾 
  ^$              空行
  .               匹配任意单字符
  .+              匹配任意多个字符
  .*              匹配0个或多个字符(可有可无)
  [0-9a-z]        匹配中括号内任意一个字符
  [abc]           表示匹配一个字符,这个字符必须是abc中的一个。
  (linux)+        出现多次Linux单词
  (web){2}        web出现两次以上
  \               屏蔽转义

​ grep基本操作:

1、查找输出特定字符
[root@krist www]# grep "sun" test
 sun01
 sun02
 sun03  
2、查找输出特定字符和前几行(Before)的信息
[root@krist www]# grep -B 1 "02" test     //前一行
 file01
 file02
 --
 test01
 test02
 --
 sun01
 sun02
 --
 moon01
 moon02
3、查找输出特定字符和后几行(After)的信息
[root@krist www]# grep -A 1 "02" test 
 file02
 file03
 --
 test02
 test03
 --
 sun02
 sun03
 --
 moon02
 moon03
4、查找输出特定字符和上下几行(Center)的信息
[root@krist www]# grep -C 1 "02" test 
 file01
 file02
 file03
 test01
 test02
 test03
 sun01
 sun02
 sun03
 moon01
 moon02
 moon03
5、统计特定字符出现次数(count)有多少行
[root@krist www]# grep "03" test 
 file03
 test03
 sun03
 moon03
[root@krist www]# grep -c "03" test 
 4
6、查找输出不符合条件的行
[root@krist www]# grep -v "test01" test 
 file01
 file02
 file03
 test02
 test03
 sun01
 sun02
 sun03
 moon01
 moon02
 moon03

grep其他用法

grep -n 'root' /etc/passwd :查找/etc/passwd下包含 root字符串的文件
grep -Ev "root|nologin" /etc/passwd :查找不包含root和nologin关键字的行
grep "root" /etc/{passwd,shadow}:查找/etc/passwd和/etc/shadow文件中包含root关键字的行
grep -c root /etc/passwd :统计/etc/passwd文件中包含root字符串行的数量
grep -E -v "^$|^#" /etc/nginx/nginx.conf : 去除空号和以#号开头的行
seq 1 20 |grep -m 5 -E '[0-9]{2}' :输出匹配的前五个结果
seq 1 20 |grep -c -E '[0-9]{2}' :输出匹配多少行
echo "a bc de" |xargs -n1 |grep '^b' :匹配以字符串"b"开头的行
echo "a ab abc abcd abcde" |xargs -n1 |grep -n 'de$' :匹配以"de"字符串结尾的行
grep -r 'sshd' /etc --include *.conf :递归搜索/etc 目录下包含 "sshd"字符串 的 conf 后缀文件
seq 41 45 |grep -E '4[12]' :匹配41/42数字

sed命令操作详解:

​ sed执行过程:(不会改变文件,一次读一行)

sed执行过程

sed常用参数:

      d  删除选择的行  
      s  查找  
      y  替换
      i  当前行前面插入一行
      a  当前行后面插入一行
      p  打印行    
      q  退出
      -n     # 只列出sed处理的哪一行内容
      -e     # 直接在sed模式上进行sed动作编辑
      -f     # 直接将sed动作写在一个文件内
      -r     # 让sed指令支持扩展的正则表达式
 替换符:
      数字 :替换第几处  
      g : 全局替换  
      \1: 子串匹配标记,前面搜索可以用元字符集\(..\)
      &: 保留搜索刀的字符用来替换其他字符

​ sed基本操作:

1、查找并打印特定字符
[root@krist www]# sed -n "/01/p" test     //参数n代表取消默认输出,即只输出匹配项,p表示print
 file01
 test01 test01 test01
 sun01
 moon01
2、替换并打印所有匹配字符
[root@krist www]# sed 's/test/rain/' test 
 file01
 file02
 file03
 rain01 test01 test01
 rain02
 rain03
 sun01
 sun02
 sun03
 moon01
 moon02
 moon03
3、全局替换
[root@krist www]# sed 's/test/rain/g' test
 file01
 file02
 file03
 rain01 rain01 rain01
 rain02
 rain03
 sun01
 sun02
 sun03
 moon01
 moon02
 moon03
4、替换指定行数
[root@krist www]# sed '4,5s/test/rain/' test  //只替换4到5行,可以用$表示最后一行
 file01
 file02
 file03
 test01 test01 test01
 rain02
 test03
 sun01
 sun02
 sun03
 moon01
 moon02
 moon03
5、删除特定行数并打印到屏幕,=;显示行号
[root@krist www]# sed '=;2,5d' test
1
file01
2
3
4
5
6
test03
7
sun01
8
sun02
9
sun03
10
moon01
11
moon02
12
moon03
6、替换特定行的所有内容并打印到屏幕
[root@krist www]# sed '4,5c new content' test
 file01
 file02
 file03
 new content
 test03
 sun01
 sun02
 sun03
 moon01
 moon02
 moon03
7、提取前两行的数据并替换特定信息
[root@krist www]# sed -e '3,$d' -e 's/file/root/' test
 root01
 root02
8、打印以特定字符开始或结尾的行
[root@krist www]# sed -n '/^m/p' test //开头
 moon01
 moon02
 moon03
[root@krist www]# sed -n '/01$/p' test    //结尾
 file01
 test01 test01 test01
 sun01
 moon01
[root@krist www]# sed -n '/^t/,/02$/p' test    //打印以“t开头”到“02结尾”的所有行
 test01 test01 test01
 test02
 test03
 sun01
 sun02
9、引用系统变量,注意是双引号
[root@krist www]# a=2
[root@krist www]# sed -n "$a,4p" test
 file02
 file03
 test01 test01 test01
10、去除空行或开头#号的行
[root@krist www]# sed '/^#/d;/^$/d' my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
!includedir /etc/my.cnf.d
[root@krist www]# sed '/^\s*$/d' my.cnf       //删除文本内空白的内容
[root@krist www]# sed '/^#.*/d' my.cnf        //删除文本注释内容
11、用取地址符&引用匹配内容并替换
[root@krist www]# sed 's/file03/& file03/' test
file01
file02
file03 file03
test01 test01 test01
test02
test03
sun01
sun02
sun03
moon01
moon02
moon03
12、匹配"48129/tcp"并将此行的"blp5"替换成"test"
[root@krist www]# tail /etc/services | sed -n '/48129\/tcp/s/blp5/test/p'
test            48129/tcp               # Bloomberg locator
[root@krist www]# 
13、添加行

​ i: 匹配行上面添加
​ a: 匹配航下面添加
​ c: 将匹配航替换成新内容

在'sun01'的上一行添加'test04'i
[root@krist www]# sed '/sun01/i \test04' test
file01
file02
test01 test01 test01
test02
test03
test04
sun01
sun02
在'sun02'的下一行添加'sun03'a
[root@krist www]# sed '/sun02/a \sun03' test
file01
file02
test01 test01 test01
test02
test03
sun01
sun02
sun03
将匹配字符所在行整行替换为对应字符串c
[root@krist www]# sed '/sun/c \rain' test
file01
file02
test01 test01 test01
test02
test03
rain
rain
tail /etc/services |sed '2a \test' : 在第二行下面添加"test"
tail /etc/services |sed '/blp5/r a.txt' : 将文件读取追加到匹配行下面
tail /etc/services |sed '/blp5/w b.txt' :将匹配行写入"b.txt"
awk命令操作详解:

​ 域

​ 类似数据库列的概念,但它是按照序号来指定的,比如我要第一个列就是,第二列就是2,依此类推。$0就是输出整个文本的内容。默认用空格作为分隔符,当然你可以自己通过-F设置适合自己情况的分隔符。

1、awk指令说明

  1. awk是一种编程语言,用于在linux下对文本和数据进行处理

    awk的处理文件和数据处理方式是逐行扫描,寻找到匹配的行,并在这些行上进行你想要的操作

           3. 如果没有指定处理动作,则把匹配的行显示到屏幕上
//              # 匹配代码块,可以是字符串或正则表达式
{}              # 命令代码块,包含一条或多条命令
$0              # 表示整个当前行
$1              # 每行第一个字段
NF              # 字段数量变量
NR              # 每行的记录号,多文件记录递增
/[0-9][0-9]+/   # 两个或两个以上数字
/[0-9][0-9]*/   # 一个或一个以上数字
-F'[:#/]'       # 定义三个分隔符
FNR             # 与NR类似,不过多文件记录不递增,每个文件都从1开始
\t              # 制表符
\n              # 换行符
FS              # BEGIN时定义分隔符
RS              # 输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
~               # 匹配,与==相比不是精确比较
!~              # 不匹配,不精确比较
==              # 等于,必须全部相等,精确比较
!=              # 不等于,精确比较
&&             # 逻辑与
||              # 逻辑或
+               # 匹配时表示1个或1个以上
1、查找并打印匹配字符
[root@krist www]# awk "/test/" test
test01 test01 test01
test02
test03
2、打印对应的列数
[root@krist www]# awk '{print $1}' test       //打印第一列
1
4
7
10
13
16
[root@krist www]# awk '{print $1,$3}' test        //打印第一列和第三列
1 3
4 6
7 9
10 12
13 15
16 18
[root@krist www]# awk '{print $0}' test       //打印所有文本
1 2 3
4 5 6
7 8 9
10 11 12
13 14 15
16 17 18

参考:

https://mp.weixin.qq.com/s/BX4VCyMpOa7iTyouzt9mbA

https://www.cnblogs.com/errenjune/p/12506830.html

https://www.cnblogs.com/yemu/p/12233591.html

真正修改替换文件内容

​ 1、vim替换:
​ :%s#aaa#bbb#g
​ :%s/aaa/bbb/g

​ 2、sed实现替换:

[root@krist www]# sed -i 's#sun#rain#g' test1
[root@krist www]# more test1
file01
file02
test01 test01 test01
test02
test03
rain01
rain02
rain03

tr命令使用技巧:

​ tr用法:和sed类似,只能实现打印在屏幕上,无法直接修改文件

[root@krist www]# tr "sun" "rrr" < test1 //逐字替换
file01
file02
test01 test01 test01
test02
test03
rrr01
rrr02
rrr03
1、将匹配文件字符替换为大写或替换为小写

​ 'A-Z' 和 'a-z'都是集合,集合是可以自己制定的,例如:'ABD-}'、'bB.,'、'a-de-h'、'a-c0-9'都属于集合,集合里可以使用'\n'、'\t',可以可以使用其他ASCII字符。

[root@krist www]# tr 'a-z' 'A-Z' < test1
FILE01
FILE02
TEST01 TEST01 TEST01
TEST02
TEST03
RAIN01
RAIN02
RAIN03
2、使用tr删除字符
[root@krist www]# tr -d '0-9' < test1  //删除文件内0-9的数字字符
file
file
test test test
test
test
rain
rain
rain
3、将换行符转换为空格
[root@krist www]# tr '\n' ' ' < test1
4、使用tr压缩字符
[root@krist www]# echo "thissss is      a text linnnnnnne." | tr -s ' sn'
this is a text line.
5、将不在集合内的所有字符删除
[root@krist www]# tr -d -c '0-9 \n' < test1        //只保留引号内的补集
01
02
01 01 01
02
03
01
02
03
6、使用tr做数字相加操作
[root@krist www]# echo 1 2 3 4 5 6 7 8 9 | xargs -n1 | echo $[ $(tr '\n' '+') 0 ]
45
7、将PATH变量每个目录显示在独立的一行
[root@krist www]# echo $PATH | tr -s : '\n'
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/root/bin
8、将由字母组成的单词显示在独立的一行
[root@krist www]# cat /etc/redhat-release | tr -sc '[:alpha:]' '\n'
CentOS
Linux
release
Core
9、生成固定长度的随机密码
[root@krist /]# head /dev/urandom | tr -dc 'A-Za-z0-9' | head -c 20
tr可以使用的字符类:
[:alnum:]:字母和数字
[:alpha:]:字母
[:cntrl:]:控制(非打印)字符
[:digit:]:数字
[:graph:]:图形字符
[:lower:]:小写字母
[:print:]:可打印字符
[:punct:]:标点符号
[:space:]:空白字符
[:upper:]:大写字母
[:xdigit:]:十六进制字符

使用方式:

tr '[:lower:]' '[:upper:]'

参考:

https://www.cnblogs.com/bingguoguo/articles/9188703.html

https://www.cnblogs.com/linyfeng/p/9075062.html

https://blog.csdn.net/li575098618/article/details/49818817

什么是inode,什么是block

​ 所谓的inode就是索引节点(index node)的意思,相当于c语言里的指针,指向存储的块数据block,每个文件都占用一个独立的inode表,默认为128字节(EXT2/3)或256字节(ext4),inode节点的总数,在格式化时就给定。inode用来存储文件属性信息,其中包括了文件大小、文件的归属者和归属组、权限、类型、修改时间以及指向文件实体数据(block)的指针(记录一个block一般为4B,当文件的inode写满后,系统会自动分配一个block块)。

inode特点:

​ 1.inode 是存放文件属性

​ 2.我们每创建一个文件占用一个inode(一般256字节)

​ 3.inode 还会存放block的位置信息(指向)

​ 4.inode 节点号相同的文件,互为硬链接文件,可以理解为是一个文件的 不同入口(一个超市,多个入口)

​ 5.inode 号码在一个分区(文件系统)是唯一的inode文件内记载的信息如下,不包含文件名,一个文件的文件名,存储在上级目录的block中:

  • ​ 文件的字节数 (size)
  • ​ 文件拥有者的User ID (user)
  • ​ 文件的Group ID (group)
  • ​ 文件的读、写、执行权限 (read,write,execute)
  • ​ 该文件的特殊权限(SUID,SGID,SBIT)
  • ​ 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。(ctime,mtime,atime)
  • ​ 链接数,即有多少文件名指向这个inode
  • ​ 文件数据block的位置 (point)
    6_inode表格式

​ block磁盘块,为数据的实际存储区。硬盘的最小存储单位叫做"扇区"(Sector),每个扇区储存512字节。操作系统读取扇区的时候是一次性读取多个扇区,即为多个”块“。“块”是文件系统的最小单位,块的大小centos默认为4KB(有1k,2k,4k,除引导分区1k外,其他分区为4k),即连续8个sector组成一个block。

block特点:

​ 1.block实际存放数据的空间

​ 2.block 一般是4k(还有 1k,8k centos 默认4k)

​ 3.一般大文件会占用多个block,如果文件很小,4k中剩余的空间会被浪费

​ 4.在Linux中创建一个文件,会占用一个 inode和只是一个block

​ 5.每读取一个block,就会消耗一次磁盘I/O

5_文件系统inode与block

​ block的大小与业务与磁盘的I/O性能有着密不可分的关系,并非越大越好或越小越好。假如说一个block的大小为4k,磁盘里有一个小文件是1k,那么这个小文件会把4k的一整个block全部占用,剩下的3k就白白浪费掉了。
​ 如果单个文件很大的情况下,block设置的很小,就需要读取多个block,这对磁盘I/O是一种消耗(因为每读取一个block都会消耗磁盘I/O,磁盘每次读取都是以block为单位的)

inode和block查看方法:

ls -i 查看inode号
ls -li 以列表查看
ls -lhi 数据大小单位转换
df -i 查看系统中inode使用情况
df -h 查看磁盘block使用情况
stat 文件或目录名 查看某个文件的inode和block信息,链接数量等
dumpe2fs -h /dev/sda1 | grep "Inode size" 查看每个inode节点的大小

[root@krist /]# sudo dumpe2fs -h /dev/sda1 | grep "Inode size"    //查看每个inode节点的大小
dumpe2fs 1.42.9 (28-Dec-2013)
Inode size:               256

由于每个文件都必须有一个inode,因此有可能发生inode已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件。要解决这个问题,只能是删除一些文件,但是一般情况下,其实是你的系统中的某个地方产生了大量的你并不需要的文件,你要做的就是找到他们并删除就可以了,我并不是让你删除你有用的文件,因为你一般不会有那么多有用的文件来把系统的 inode 用光。

如何查找哪个目录下文件最多

cd /
然后执行

for i in /*; do echo $i; find $i | wc -l; done

或者

for i in `ls -1A | grep -v "\.\./" | grep -v "\./"`; do echo "`find $i | sort -u | wc -l` $i"; done | sort -rn | head -10

如何删除那个目录的的所有文件

find 目录 -type f -name '*' -print0 | xargs -0 rm

时间可能会比较久,所以你最好开一个 screen 来处理

也有可能是遇到了以下情况:
/var/spool/postfix/maildrop 下面有很多文件
为了避免,可以执行 crontab -e
在最开头添加 MAILTO='"' 保存,然后 server crond restart重启 crond

参考:

https://www.cnblogs.com/itech/archive/2012/05/15/2502284.html

linux文件系统—inode及相关概念 inode大小的最佳设置

什么是硬链接,什么是软连接

硬链接(Hard Link),指通过索引节点来进行连接。原理上,硬链接和源文件的inode节点号相同,即多个文件名指向同一节点号。硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。

硬链接特点:

​ 1、具有相同inode节点号的多个文件互为硬链接文件;
​ 2、删除硬链接文件或者删除源文件任意之一,文件实体并未被删除;
​ 3、只有删除了源文件和所有对应的硬链接文件,文件实体才会被删除;
​ 4、硬链接文件是文件的另一个入口;
​ 5、可以通过给文件设置硬链接文件来防止重要文件被误删;
​ 6、硬链接文件是普通文件,可以用rm删除;
​ 7、对于静态文件(没有进程正在调用),当硬链接数为0时文件就被删除。注意:如果有进程正在调用,则无法删除或者即使文件名被删除但空间不会释放;
​ 8、不能对目录创建硬链接,不能对不同文件系统创建硬链接,不能对不存在的文件创建硬链接。

93_硬链接文件

硬链接创建方法:ln [源文件] [硬链接文件]

[root@krist www]# ln test1 test3
[root@krist www]# ll -ih test1 test3
30 -rw-r--r--. 2 root root 98 Aug  9 15:09 test1
30 -rw-r--r--. 2 root root 98 Aug  9 15:09 test3
[root@krist www]# stat test1
  File: ‘test1’
  Size: 98              Blocks: 8          IO Block: 4096   regular file
Device: 811h/2065d      Inode: 30          Links: 2
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: unconfined_u:object_r:default_t:s0
Access: 2020-08-12 13:13:14.202762952 +0800
Modify: 2020-08-09 15:09:45.726046708 +0800
Change: 2020-08-12 13:13:34.418958805 +0800
 Birth: -
[root@krist www]# stat test3
  File: ‘test3’
  Size: 98              Blocks: 8          IO Block: 4096   regular file
Device: 811h/2065d      Inode: 30          Links: 2
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: unconfined_u:object_r:default_t:s0
Access: 2020-08-12 13:13:14.202762952 +0800
Modify: 2020-08-09 15:09:45.726046708 +0800
Change: 2020-08-12 13:13:34.418958805 +0800
 Birth: -

即使删除了test1,硬链接文件test3依旧存在

[root@krist www]# rm test1
rm: remove regular file ‘test1’? y
[root@krist www]# ll -ih test3
30 -rw-r--r--. 1 root root 98 Aug  9 15:09 test3

软链接(Symbolic Link),相当于windows中的快捷方式,软链接创建的文件为一个独立的新文件,因此软链接和源文件的inode号不同,指向的block也不同,软链接block中存放了源文件的路径名,即源文件的位置信息。和windows的快捷方式一样,删除了源文件,软链接也会失效。

软链接特点:

  1. 软链接类似windows系统的快捷方式;
  2. 软链接里面存放的是源文件的路径,指向源文件;
  3. 删除源文件,软链接依然存在,但无法访问源文件内容;
  4. 软链接失效时一般是白字红底闪烁;
  5. 软链接和源文件是不同的文件,文件类型也不同,inode号也不同;
  6. 软链接的文件类型是“l”,可以用rm删除;
  7. 可以对目录创建软连接,可以跨文件系统创建软连接,可以对不存在的文件创建软连接。

94_软链接文件

软链接创建方法:ln -s [源文件或目录] [软链接名字]

[root@krist www]# ln -s test3 test4
[root@krist www]# ls -ihl test3 test4
30 -rw-r--r--. 1 root root 98 Aug  9 15:09 test3
27 lrwxrwxrwx. 1 root root  5 Aug 12 13:31 test4 -> test3
[root@krist www]# stat test3 test4
  File: ‘test3’
  Size: 98              Blocks: 8          IO Block: 4096   regular file
Device: 811h/2065d      Inode: 30          Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: unconfined_u:object_r:default_t:s0
Access: 2020-08-12 13:13:14.202762952 +0800
Modify: 2020-08-09 15:09:45.726046708 +0800
Change: 2020-08-12 13:16:20.698737718 +0800
 Birth: -
  File: ‘test4’ -> ‘test3’
  Size: 5               Blocks: 0          IO Block: 4096   symbolic link
Device: 811h/2065d      Inode: 27          Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Context: unconfined_u:object_r:default_t:s0
Access: 2020-08-12 13:31:20.391143484 +0800
Modify: 2020-08-12 13:31:02.167977571 +0800
Change: 2020-08-12 13:31:02.167977571 +0800
 Birth: -

删除源文件后,test4失效无法访问,ls查看时,test3会不停闪烁

[root@krist www]# rm -f test3
[root@krist www]# more test4
test4: No such file or directory
[root@krist www]# ls -ihl test4
27 lrwxrwxrwx. 1 root root 5 Aug 12 13:31 test4 -> test3
总结:

a.Inode是存放文件属性信息的,默认大小128byte(c58),256byte(c64);
b.Block是存放文件实际内容的,默认大小1K (boot)或4K (非系统分区默认给4K);
c.一个文件至少要占用一个inode及一个block;
d.默认分区常规情况下,inode 是足够的。而block消耗的会更快。因此,一般都是block被耗尽。
1) 磁盘分区格式化文件系统后,会分为inode和block两部分内容;
2) inode存放文件的属性以及指向文件实体的指针,文件名不在inode里,在上级目录的block中;
3) 访问文件,通过文件---inode---block;
4) inode 一般般情况默认大小256B,block大小1K 2K 4K,默认是4K,注意,引导分区等特殊分区除外;
5) 通过df -i查看inode的数量及使用情况,dumpe2fs /dev/sda1查看inode及block的大小及数量;
6) 一个文件至少要占用一个inode及一个block,多个文件可以占用同一个inode(硬链接);
7) 一个block只能被一个文件使用,如果文件很小block很大,剩余空间浪费,无法继续被其他文件使用;
8) block不是越大越好,要根据业务的文件大小进行选择,一般就是默认4K;
9) 可以在格式化的时候改变inode及block的大小。

 收藏 (0) 打赏

您可以选择一种方式赞助本站

支付宝扫一扫赞助

微信钱包扫描赞助

未经允许不得转载:DDblog » Linux云计算系统学习第七天

分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

立即登录   注册

DD博客

联系我们每天好心情
切换注册

登录

忘记密码 ?

切换登录

注册

我们将发送一封验证邮件至你的邮箱, 请正确填写以完成账号注册和激活