linux shell文本过滤 正则表达式 grep 文本过滤 shell如何统计文本文件行数
(1) 正则表达式
比如:找txt结尾的文件名
^ 只匹配行首 ^d 以d开始 ls | grep ^b.sh 显示以b开头的文件
$ 只匹配行尾 e$ 匹配以 e结尾的所有字符 ls | grep for1$ 显示以1结尾的文件
* 匹配0或多个单字符
[] 只匹配[]内字符,如[1-5]替代[12345] [a,A]
\ 屏蔽一个元字符的特殊含义(",',||,*,+) \*\.pas 匹配以*.pas 结尾的所有字符
. 只匹配任意单字符 ^d...1
^$ 匹配空行
A\{2\}B A出现2次,AAB
A\{4,\}B A最少出现3此
A\{2,4\}B 出现次数范围2-4次
[0-9]\{3\}.[0-9]\{3\}.[0-9]\{3\}.[0-9]\{3\} -->匹配ip地址
(2) find
find pathname -options [-print -exec -ok]
patchname : 路径
ok 和exec : 作用相同,ok更安全,执行命令提示用户是否执行
options 包括
-name 文件名
perm 文件权限
user 文件属主
size n[c] 文件长度为n块的文件
find -name "*.txt" -print -->当前路径,输出到屏幕
find -name "[A-Z]*" -print -->以A-Z开头的大写文件
find -perm 755 -->根据权限查找
find `pwd` -user root -->当前路径查找用户是root的文件
find `pwd` -nouser -->查看文件没有用户的
find / -nouser -->查找整个系统不存在用户的文件(由于删除用户没有删除用户的文件)
find -group itlab -->查看这个组的所有文件
find -nogroup -->查看没有组的文件
find /var -mtime -5 -->改变时间在5天之内的
find / -mtime -1 -->最近1天改变的文件
+3 -->3天以前发生改变的文件
find -newer "file1" ! -newer "file2" -->比 file1 新,但是比file2 旧的文件,之间
find /etc/ -type d -->查看etc下 文件类型为d的文件
find -size 1000c -->查看大于 1k字节的文件
find -size 10 -->查看大于10个块
find . -type f -exec ls -l {} \; -->查找文件,显示信息,注意空格
find . -name "*.log" -mtime +5 -ok rm {} \; -->查找5天前的日志,然后删除
注意:exec 执行命令有限,会溢出,会发起多个进程,而xargs不会多个,只有一个
find -name a.txt | xargs chmod 777
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
grep 文本过滤
grep [选项] "基本正则表达式" [文件]
-c 只输出匹配行的计数
-i 不区分大小写(只适用于单字符)
-h 查询多文件时不显示文件名
-H 显示文件名
-l 查询多个文件时只输出包含匹配字符的文件
-n 显示匹配行及行号
-s 不显示不存在或无匹配文本的错误信息
-v 显示不包含文本的所有行
测试:
gerp "aa" *.txt -->从所有*.txt 文件中查找带 aa
grep "aa" * -->所有文件查找带 aa
grep -c "aa" name.txt -->有多少行与aa匹配,就是带aa的一共有多少行
grep -n "aa" name.txt -->显示在哪行,行号显示出来
grep -i "bb" name.txt -->不区分大小写
grep -v "bb" name.txt -->过滤掉带bb的行
grep "Dec 20 15:39:3[1-9]" maillog -->过滤
grep "^[^210]" myfile -->开头不是210的文件
grep "[5-8][6-9][0-3]" myfile -->一个3位数
grep "a\{4\}" name.txt -->每行 a连续出现4次以上的
grep "a\{2,4\}" name.txt -->连续2个到4个以上的
grep "a\{2,\}" name.txt -->最少出现2次
grep "^$" name.txt -->显示空行,-n 显示在哪个行是空行
grep "\?" name.txt -->查找文件中带 ?的
grep "^d" name.txt --> d开头的行
grep "^[^lpd]" name.txt -->不要显示以 lpd 开头的文件
-----------------------------------------------------------------------------------------------------
egrep
-i 进行比较时忽略大小写
$ egrep -i "B" a.txt
-------------------------------------------------------------------------------------
awk 可从文件或字符串中基于指定规则浏览和抽取信息,是一种自接受的编程语言
命令调用:awk [-F filed-spearator]'command' input-files
awk脚本: 所有awk命令插入一个文件,并使awk程序可以执行,然后用awk 命令解释作为脚本的首行
以便键入脚本名称来调用它。
awk命名插入一个单独文件 awk -f awk-script input-files
awk 脚本由各种操作和模式组成
模式和动作
模式部分决定动作语句何时触发及触发事件。(BEGIN END)
动作对数据进行处理,放在大括号{} 内指明。(print)
分隔符、域和记录
awk执行时,其浏览域标记为 $1,$2 ... $n 这种方法称为域标识。$0为所有域。
注意执行时不要混淆符号$和shell提示符 $,它们是不同的
aaaa bbbb cccc
一行记录:以空格划分域,
测试1
awk '{print $0}' name.txt | tee name.out -->全部输出,并且输出到name.out文件里 $1只输出第一列
-F 省略,默认空格
awk '{print $1"\t"$2}' name.txt -->中间用 tab 分开
awk 'BEGIN {print "id name \n--------" } -->头,注意必须大写,单引号
{print $1"\t"$2} END
{print "end"}'
name.txt -->尾
awk 特殊字符 + 任意字符 ?单个字符
操作符 ~ 匹配 !~ 不匹配
awk '$1~/192.168.88.2/' name.txt -->在第一列中取 192.168.88.2这个值
awk '$1!~/192.168.88.2/' name.txt -->显示不匹配的行
awk '{if ($1=="192.168.88.2") print$0}' name.txt -->如果第一列中等于 192.168.88.2 则打印这行
info awk -->帮助信息
---------------------------------------------------------------------------------------------------------
sed
不与初始文件打交道,它操作的只是一个拷贝,然后所有的改动重定向到一个文件,将输出到屏幕
命令格式:sed [选项] sed 命令输入文件
sed脚本文件:sed [选项] -f sed 脚本文件输入文件
sed脚本文件[选项]输入文件
不管是使用shell命令行方式或脚本文件方式,如果没有指定输入文件,sed从标准输入中
接受输入,一般是键盘或重定向结果
命令选项
n 不打印(没有匹配的)
c 下一命令是编辑命令
f 如果正在调用 sed 脚本文件
查询文本方式
x x为一行号
x,y 表示行号范围从x 到y
/pattern/ 查询包含模式的行
/pattern/pattern/ 查询包含两个模式的行
pattern/,x 给定行号上查询包含模式的行
x,/pattern/ 通过行号和模式查询匹配行
x,y! 查询不包含指定行号x和y的行
p 打印匹配行
= 显示文件行号
a\ 在定位行号后附加新文本信息
i\ 在定位行号后插入新文本信息
d 删除定位行
c\ 用新文本替换定位文本
s 使用替换模式替换相应模式
r 从另一个文件中读文本
w 写文本到一个文件
q 第一个模式匹配完成后推出或立即退出
l 显示8进制 ASCII代码等价的控制字符
{} 在定位行执行的命令组
n 从另一个文件中读文本下一行,并附加在下一行
g 将模式2粘贴到 /pattern n/
y 传送字符
测试:
sed -n '2p' name.txt -->只打印第2行
sed -n '1,4p' name.txt -->打印1-4行
sed -n '/iii/p' name.txt -->打印带有 iii 的所有行
sed -n '4,/logs/p' name.txt -->从第4行开始匹配,找到一个就停止
sed -n '/^$/=' name.txt -->显示空行行号
sed -n -e '/^$/p' -e '/^$/=' name.txt -->显示空行及行号
sed '/aaaa/a \wy' name.txt -->在每个aaa 行后面增加 wy 一行 (老版本要换行)
sed '/aaaa/i \wy' name.txt -->前面插入
sed '/aaaa/c \wywy' name.txt --->aaaa 用 wywy替换
sed '1,2d' name.txt -->第一行,第二行删除 (要是1,3 就是1-3行)
sed 's/aaaa/wwww/g' name.txt -->aaaa 用 wwww 替换 g代表全部,不加默认也是全部
sed -n 's/aaaa/& hello/p' name.txt -->匹配之后加 hello,显示出来(aaaa hello)
hello & -->加载到匹配字符之前
sed 'lr ctrl.txt' myfile.txt
info sed 帮助
-------------------------------------------------------------------------------------
合并与分割 :许多不同的域按不同的列顺序分类
c 测试文件是否已经分类
m 合并两个分类文件
u 删除所有复制行
o 存储sort结果的输出文件名
t 域分割符;用非空格或 tab 键分割域
+n n 为域号,使用此域号开始分类
n 指定分类是域上的数字分类项
r 比较求逆
测试:
sort -c name.txt -->检查文件是否排序
sort -u name.txt -->压缩重复行
sort -r name.txt -->倒叙排列
sort -rn name.txt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
uniq [option] files
从一个文本中去除或禁止重复行
u 只显示不重复行
d 只显示有重复数据行,每种重复行只显示其中一行
c 单元每一重复行出现次数
f n为数字,前n个域被忽略
eniq -c name.txt -->压缩重复行只显示不重复的,但是这两行必须相邻,主要用查有多少行是重复的
eniq -d name.txt -->只显示重复行
eniq -f 2 name.txt -->前2个域忽略
解决不是邻居两行不压缩
sort name.txt |uniq -c 或 sort -u name.txt
查看有多少个ip访问
awk '{print $1}' name.txt |sort | uniq -c -->经典
grep "php"|awk '{print $1}'|sort | uniq -c --> php 有多少访问
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
join [options] file1 file2
用来将来两个分类文本文件的行连在一起
an n为数字,用于连接时从文件n中显示不匹配行
o n.m 连接域,n为文件号,m为域号
j n m n为文件号,m为域号,使用其他域做连接符
t 域分割符,用来设置非空格或 tab 键的域分割符
测试:
join w1 w2 -->只w1 与w2 相同的行显示出来
join -a1 w1 w2 -->显示w1所有记录,包括与w2相同的,w2不匹配的显示空白
join -a2 w1 w2 -->同时,反过来
join -a1 -a2 w1 w2 -->全部显示出来,相同行只显示一次
join -o 1.1 2.2 w1 w2 -->首先显示相同列,显示w1的 第1列,w2的第2列
join -t ':' /etc/passwd /etc/shadow
split -output_file-size input-filename output-filename
-b n,每个分割文件大小n (k,m)
-C n,每个分割文件一行最多n字节数
-l n,每个分割文件的行数
-n 同 -l n
split -10 ls_out.txt split_ -->每10行分割成一个文件,以split 开头
cut 用来从标准输入或文本文件中剪切列或域
是以每一行为一个处理对象的,这种机制和sed一样的
举例:$ who
root pts/0 2011-02-23 08:39 (10.230.3.150)
$ who |cut -b 3 --> -b 按字节
o
$ who | cut -b 3-5 -->取3-5字节
注意:英文 -b 与 -c一样,中文不一样
有用的: $cat /etc/passwd | head -n 10 | cut -d : -f 1 -->前10行,以:为分割符,取第一列
空格与制表符号处理
$cat /etc/passwd | head -n 10 | cut -d ' ' -f 1 -->取空格
$cat /etc/passwd | head -n 10 | cut -f 1 -->制表符省略 -d
paste 将按行将不同文件行信息放在一行
FILE_NAME=/home/work/filter/20100908141530/561445/results/0/logdiff/mvp.diff
RES_LINE=`wc -l $FILE_NAME | awk '{print $1}'`
echo $RES_LINE
http://hi.baidu.com/visual_art/item/add606c8c55300c6984aa0c5
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?