sed、awk、grep

各有侧重

文件上传工具:Tiny File Manager的数据备份时,用到sed处理记录文件。

  • sed 是一种流编辑器,主要用于对文本进行替换、删除、插入等操作。它逐行处理输入文本,并输出修改后的结果。
  • awk 是一种以字段为单位的文本处理语言,擅长数据提取、统计和格式化输出。
  • grep 是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。

grep 使用

在目录下,搜索所有文件与子目录的文件:grep -inr 'logdn' ./

过滤配置文件中被注释的行:grep -Ev '^$|^\s*#' /etc/nginx/nginx.conf

查找多个关键字:ps -Ao user,pid,ppid,%mem,rss,%cpu,cmd --sort=+ppid|grep -E 'PID|nginx|php-fpm|mariadb'

常用选项

  • -E:扩展正则表达式
  • -i:忽略大小写进行匹配。
  • -v:反向查找,只打印不匹配的行。
  • -n:显示匹配行的行号。
  • -r:递归查找子目录中的文件。
  • -l:只打印匹配的文件名。
  • -c:只打印匹配的行数。

grep 的一行多个关键字之间 and / or / not 匹配

与(AND)操作

  • 使用管道符将多个grep命令连接起来,这样只有同时满足所有条件的行才会被显示。例如:grep 'pattern1' filename | grep 'pattern2'
  • 使用-E选项,结合正则表达式来实现与操作。例如:grep -E 'pattern1.*pattern2' filename或者grep -E 'pattern1.*pattern2|pattern2.*pattern1' filename,区别在于是否有先后出现顺序。

或(OR)操作

  • 使用转义字符将管道符转为“或”符号:grep 'pattern1\|pattern2' filename
  • 使用-E选项:grep -E 'pattern1|pattern2' filename或者egrep 'pattern1|pattern2' filename
  • -e选项:grep -e pattern1 -e pattern2 filename

非(NOT)操作

  • 使用-v选项,这样可以显示不符合指定模式的所有行。例如:grep -v 'pattern' filename

sed使用

Bash
sed -i '1i\'"${outText}" ${targetDIR}/${logFileName} # 将内容插入到第1行的前面,注意变量引用方式,"1i\${outText}"是无效的。'
  • -i 是指编辑已有文件${targetDIR}/${logFileName},如果没有此参数,只是显示处理后结果,文件不会被修改。
  • '1i\'"${outText}"是指在第一行的前面,插入内容${outText}
    • 1代表行数,需要在文件中存在,否则会处理失败,且不会有报错提示。
    • i\代表行的前面插入内容,而a\代表行的后面插入内容。
Bash
sed -i "s|${targetDIR}||" ${targetDIR}/${logFileName} # 替换targetDIR为空
  • "s|${targetDIR}||"是查找变量值+替换为空,也就是删除。一般格式是's/查找内容/替换内容/',由于${targetDIR}是路径,包含了[/],所以使用[|]做为分隔符。也可使用其他特殊字符,做为分隔的定界符,比如[:]

更多:

  • 删除空白行:sed '/^$/d' file
  • 删除文件的第2行:sed '2d' file
  • 删除文件的第2行到末尾所有行:sed '2,$d' file
  • 删除文件最后一行:sed '$d' file
  • 删除文件中所有开头是test的行:sed '/^test/'d file

正则表达式替换

Bash
echo this is digit 7 in a number | sed 's/digit ([0-9])/\1/'
this is 7 in a number

awk

数值计算见:Shell中的运算符

内容提取

场景:将指定目录的文件大小与文件名,生成到一个文件里。

ll命令的输出:

total 140M
drwxrwxr-- 2 pubFiles pubFiles 4.0K Nov 28 09:30 ./
drwxr-xr-x 5 root     root     4.0K Nov 26 20:20 ../
-rw-r--r-- 1 lat      ubuntu   110M Jul 26 06:44 AxureRP-Setup-3754.exe
-rw-r--r-- 1 root     root      428 Nov 28 11:31 list.txt
-rw-r--r-- 1 lat      ubuntu    25M Oct 20 20:28 rclone-v1.71.2-linux-amd64.deb
-rw-r--r-- 1 lat      ubuntu   1.4M Jan 25  2025 rustdesk-server-hbbr_1.1.14_amd64.deb
-rw-r--r-- 1 lat      ubuntu   4.1M Jan 25  2025 rustdesk-server-hbbs_1.1.14_amd64.deb
Bash
echo `date` > /data/downloads/list.txt
# tee file.txt 命令可以同时输出到屏幕+文件里,来代替 >>
ls -lhF /data/downloads | awk '{print $5,"\t",$9}' >> /data/downloads/list.txt
cat /data/downloads/list.txt
-rw-r--r-- 1 lat      ubuntu   110M Jul 26 06:44 AxureRP-Setup-3754.exe

中间是空格分隔,连续多个视为一个。

  • $0是整行内容
  • $1是-rw-r–r–
  • $2是1
  • $3是lat
  • $4是ubuntu
  • $5是110M
  • $6是Jul
  • $7是26
  • $8是06:44
  • $9是AxureRP-Setup-3754.exe,可以看出上面命令awk '{print $5,"\t",$9}'在文件名有空格时,会不符合预期输出。
110M    AxureRP-Setup-3754.exe
0       list.txt
25M     rclone-v1.71.2-linux-amd64.deb
1.4M    rustdesk-server-hbbr_1.1.14_amd64.deb
4.1M    rustdesk-server-hbbs_1.1.14_amd64.deb

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注