Linux-文本处理工具

175 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

find、grep、argx、sort、uniq、tr、cut、wc、paste、sed、awk命令的使用说明

1. find - 文件查找

用法(usage):

find path -option [-print/-exec/-ok command] {} ;

选项(option):

  • -name:按名称查找
  • -type b/d/c/p/l/f:按文件类型查找。块设备/目录/字符设备/管道/符号链接/普通文件
  • -atime -/+:按文件访问时间查找(天)
  • -mtime -/+:按文件修改时间查找-内容被修改(天)
  • -ctime -/+:按文件变化时间查找-元数据或权限变化(天)
  • -amin -/+:按文件访问时间查找(分钟)
  • -perm:按权限查找
  • -user:按文件属主查找
  • -group:按文件所属的组来查找文件
  • -nouser:查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在
  • -newer file1 !file2:查找更改时间比文件file1新但比文件file2旧的文件
  • -maxdepth -/+:指定搜索深度
  • -size +k/M/G:按文件大小搜索

表达式(expression):

  • -print:将匹配的文件输出到标准输出
  • -exec:对匹配的文件执行该参数所给出的shell命令
  • -ok:和-exec的作用相同,在操作前询问用户

特殊说明:

  • -print的定界符,默认使用' '作为文件的定界符
  • -print0 使用''作为文件的定界符,这样就可以搜索包含空格的文件

常用命令:

# 查找txt和pdf文件
find . ( -name "*.txt" -o -name "*.pdf" ) -print
# 正则方式查找.txt和pdf
find . -regex ".*(.txt|.pdf)$"
# 查找所有非txt文本
find . ! -name "*.txt" -print
# 打印出当前目录的文件(深度为1)
find . -maxdepth 1 -type f
# 查找/var/log目录中更改时间在7日以前的普通文件,删除前询问
find /var/log -type f -mtime +7 -ok rm {} \;
# 表示find输出的每条结果后面加上 '\0' 而不是换行
find . -name "*.txt" -print0

2. grep - 文本搜索

用法(usage):

grep [option]... PATTERN [FILE]...

选项(option):

  • -o:只显示匹配PATTERN部分
  • -v:显示不包含匹配文本的所有行
  • -c:统计文件中包含文本的行数
  • -i:忽略大小写
  • -A :显示匹配行之后的内容
  • -B :显示匹配行之前的内容
  • -C :显示匹配行之前后的内容
  • -n:显示行号
  • -e:正则表达式查找
  • -l:列出匹配的文件名称
  • -r:递归

常用命令:

# 匹配多个模式
grep -e "class" -e "vitural" file
# 正则
grep 't[ae]st' file

3. argx - 传递参数过滤器

  1. argx是组合多个命令的一个工具。它擅长将标准输入数据转换成命令行参数。它能够捕获一个命令的输出,然后传递给另外一个命令
  2. xargs 默认的命令是 echo,空格是默认定界符。这意味着通过管道传递给 xargs 的输入将会包含换行和空白,不过通过 xargs 的处理,换行和空白将被空格取代
  3. 将单行或多行文本输入转换为其他格式。如多行变单行,单行变多行

用法(usage):

xargs [OPTION]... COMMAND INITIAL-ARGS...

选项(option):

  • -d:指定界符(默认为空格)
  • -n :每次传递几个参数给其后面的命令执行
  • -p:输出即将要执行的完整命令,并询问是否执行
  • -t:先打印,然后执行 -e/E :当xargs分析到含有flag这个标志的时候就停止
  • -i:用{}代替管道之前的标准输出内容
  • -I:指定一个替换字符串
  • -r:no-run-if-empty. 无参数时停止运行,默认空参数运行一次
  • -0:等价于xargs -d '\0'

常用命令:

# 多行变单行、单行变多行
cat test.txt | xargs
cat test.txt | xargs -n 3
# 统计所有php文件的行数
find . -type f -name "*.php" -print0 | xargs -0 wc -l
# 指定分隔符,三个参数一行
echo '11@22@33@44@55@66@77@88' | xargs -d '@' -n 3 echo
# 复制所有图片文件到/data/images目录下
ls *.jpg | xargs -n1 -I {} cp {} /data/images

4. sort - 排序

用法(usage):

sort [OPTION]... [FILE]...

选项(option):

  • -b:忽略每行前面开始出的空格字符
  • -n:按数字进行排序
  • -d:按字典序进行排序
  • -f:排序时,将小写字母视为大写字母
  • -r:逆序排序
  • -m:将几个排序好的文件进行合并
  • -M:将前面3个字母依照月份的缩写进行排序
  • -o<输出文件>:将排序后的结果存入指定的文件
  • -k N:指定按第N列排序
  • -t<分隔字符>:指定排序时所用的栏位分隔字符

常用命令:

# 以月份来排序
sort -n -k 2 -t'-' date
# 忽略像空格之类的前导空白字符
sort -bd data

5. uniq - 消除重复行

用法(usage):

uniq [OPTION]... [FILE]...

选项(option):

  • -c:在每列旁边显示该行重复出现的次数
  • -d:只输出重复的行
  • -u:仅显示出一次的行列
  • -i:在比较的时候不区分大小写
  • -s<字符位置>:忽略比较指定的字符
  • -w<字符位置>:指定要比较的字符

常用命令:

# 以月份来排序
uniq -n -k 2 -t'-' date
# 忽略像空格之类的前导空白字符
uniq -bd data

6. tr - 转换或删除

用法(usage):

tr [OPTION]... SET1 [SET2]

选项(option):

  • -c:反选SET1
  • -d:删除匹配SET1的内容

常用命令:

# 加解密转换,替换对应字符
echo 12345 | tr '0-9' '9876543210'
# 小写字母转大写字母
cat testfile |tr a-z A-Z 

7. cut - 按列切分文本

用法(usage):

tr [OPTION]... [FILE]...

选项(option):

  • -b:以字节为单位进行分割
  • -c:以字符为单位进行分割
  • -d:指定字段的分隔符,默认的字段分隔符为“TAB”
  • -f:显示指定字段的内容
  • --complement:与f一起使用,提取指定字段之外的列

常用命令:

# 合并文本
cut file1 file2 > file3
# 指定分隔符提取字段内容,提取第一列和第六列
who | cut -d ' ' -f 1,6
# 指定提取范围,N-:提取第N个字符到结尾,N-M:提取第N到M个字符,-M:提取第一个字符到第M个
cut -c 1-3 test.txt

8. wc - 统计行和字符

用法(usage):

wc [OPTION]... [FILE]...

选项(option):

  • -c:统计字符数
  • -w:统计单词数
  • -l:统计行数

常用命令:

# 统计文件行数
wc -l file

9. paste - 合并文件的列

用法(usage):

paste [OPTION]... [FILE]...

选项(option):

  • -d:指定分隔符
  • -s:将每个文件合并成行而不是按行粘贴

常用命令:

$ cat file1
1
2

$ cat file2
colin
book

$ paste file1 file2
1 colin
2 book

10. sed - 过滤和替换文本

用法(usage):

sed [OPTION]... {script-only-if-no-other-script} [input-file]...

选项(option):

  • -i:直接替换原文件
  • -e:script脚本
  • -n:取消默认完整输出,仅显示匹配的行
  • -g:将hold space中的内容拷贝到pattern space
  • -G:将hold space中的内容追加到pattern space
  • -h:将pattern space中的内容拷贝到hold space
  • -H:将pattern space中的内容追加到hold space

脚本动作(script):

  • a:新增,在当前行之后添加一行或多行。多行时除最后一行外,每行末尾需用“\”续行
  • c:取代,用此符号后的新文本替换当前行中的文本。多行时除最后一行外,每行末尾需用""续行
  • d:删除,删除行
  • i:插入,在当前行之前插入一行或多行。多行时除最后一行外,每行末尾需用""续行
  • p:打印,打印行
  • s:取代,用一个字符串替换另一个
  • q:退出

常用命令:

# 搜索有root关键字的行
$ nl /etc/passwd | sed -n '/root/p'
# 指定行的范围:逗号
# 仅显示第2~5行,'3,$d':删除从第三行到最后一行内容
$ nl /etc/passwd | sed -n '2,5p'
# 显示包含"hhh"的行到包含"omc"的行之间的行
$ sed -n '/hhh/,/omc/p' yum.log
# 搜索并执行命令,bash替换为blueshell,p:打印,q:退出
$ nl /etc/passwd | sed -n '/root/{s/bash/blueshell/;p;q}'    
1  root:x:0:0:root:/root:/bin/blueshell
# 替换。-i:直接替换原文件,s:替换命令,斜线是分隔符,第一段是正则表达式,第二段是替换的文本,g:全局替换
$ sed -i 's/text/replace_text/g' file
# 移除空白行
$ sed '/^$/d' file
# 变量转换,已匹配的字符串通过标记&来引用
$ echo this is en example | sed 's/w+/[&]/g'
[this] [is] [en] [example]
# 当使用双引号时,我们可以在sed样式和替换字符串中指定变量
$ p=patten
$ r=replaced
$ echo "line con a patten" | sed "s/$p/$r/g"

11. awk - 文本分析工具

用法(usage):

awk [OPTION]... 'BEGIN{awk-commands} /pattern/ {awk-commands} END{awk-commands}' [FILE]...

说明:

BEGIN{awk-commands}:开始块。程序启动的时候执行的代码部分,整个过程只执行一次 /pattern/ {awk-commands}:主体块。对于每一个输入的行都会执行一次主体部分的命令 END{awk-commands}:结束块。在程序结束时执行的代码

选项(option):

  • -F:指定分隔符
  • -v:赋值一个用户定义变量
  • -f:从脚本文件中读取awk命令

内置变量

  • FILENAME:输入的文件名称
  • FS(Field Separator):输入字段分隔符
  • OFS(Out of Field Separator):输出字段分隔符
  • RS(Record Separator):输入记录分隔符(默认:换行符)
  • ORS(Output Record Separate):输出记录分隔符(默认:换行符)
  • NR(Number of Record):行号
  • NF(Number of Field):当前行的列数
  • $NF:Number Finally,表示最后一列的信息
  • $0:指整条记录
  • $1~$n:当前记录的第几列

内置函数

  • int(num):取整函数
  • rand():返回任意数字
  • gsub:全局替换
  • sub:一次替换
  • substr(str, pos, len):截取字符串
  • index(str1,str2):下标
  • length(str):字符串长度
  • match:正则匹配
  • split(str,arr,separator):分割为数组
  • tolower(str):转小写
  • toupper(str):转大写
  • printf(fmt,args):格式化字符串。%s 字符类型,%d 数值类型,%f 浮点类型。默认不会在行尾自动换行,加\n
  • strtonum:字符串转数值

常用命令:

# 忽略大小写
$ awk 'BEGIN{IGNORECASE=1} /ROOT/' /etc/passwd
# 正则表达式,字符串匹配。~表示模式开始,//中是模式,!~表示取反
$ awk -F: '$1 ~ /^root/ {printf("%s,%s\n",$1,$NF)}' /etc/passwd
# 条件表达式,统计某个文件夹下的大于100k文件的数量和总和
$ ls -l|awk '{if($5>100){count++; sum+=$5}} END{print "Count:" count,"Sum: " sum}'
# 查看最近登录最多的IP
$ last | awk '{S[$3]++} END{for(a in S ) {print S[a],a}}' |uniq| sort -rh
# 打印处于start_pattern和end_pattern之间的文本
$ awk '/start_pattern/,/end_pattern/' filename

参考

史上最全的 Linux Shell 文本处理工具集锦