当前位置: 首页 > news >正文

Linux 文本内容处理小记

这篇笔记用来整理目前用过或者见过的一些文本处理软件,意在提升命令行和脚本对文本处理效率,发现一些可能没关注的实用技巧

简单

先上点简单易用的软件,可以完成基本的文件处理、统计和排序 

wc 统计文本信息

print newline, word, and byte counts for each file  打印文件的行数,单词数,字符数

可以统计单个文件或多个文件的行数、单词数和字符数,一般用来统计行数用的比较多

wc /etc/passwd /etc/shadow46   93 2576 /etc/passwd46   46 1897 /etc/shadow92  139 4473 total行数 单词数 字节数 文件名参数 默认(lwc):-c, --bytes-m, --chars-l, --lines-w, --wordsls -l /etc | wc -l

注意:默认的第三个参数,是字节不是字符,写中文就能测试出来默认是-c 不是 -m,但是中文的字节计算不太对

中文在不同编码下占用的字节数不同,在GB2312编码下,一个中文字符占2个字节;在GBK编码下,一个中文字符占2个或4个字节;在UTF-8编码下,一个中文字符占3个或4个字节

echo 打印显示

echo - display a line of text 显示文本中的一行

这个是shell脚本中会经常看到的文本处理命令,也不需要什么复杂的用法,完全可不用特别参数,查看man 也没有太多的参数,不过支持12个转义字符,我取了几个看着有点用的出来

man echo
echo 参数-E     disable interpretation of backslash escapes (default) 关闭反斜杠转义支持-e     enable interpretation of backslash escapes 开启反斜杠转义支持-n     do not output the trailing newline  不打印末尾的换行If -e is in effect, the following sequences are recognized:\\     backslash            打印\\n     new line             打印换行\r     carriage return      打印回车\t     horizontal tab       打印水平制表符\v     vertical tab         打印垂直制表符

 echo 参数后面的所有东西都会打印,可以拼接,可以支持取变量,但是注意单引号内原样输出

echo hello world         打印字符
ehco $PATH               打印变量
echo $(hostname)         打印执行结果
echo `hostname`          打印执行结果
echo PATH IS "$PATH"     "" 号内可以取出变量
echo '$PATH'             '' 号内原样输出
echo "hello" -n          打印结果是 hello -n ,参数记得放前面

watch 观察变化

watch - execute a program periodically, showing output fullscreen 定期执行程序,全屏显示输出

这个命令适合用来观察变化,比如文件清单、大小,内容相对固定的文件等等,变化内容可以高亮显示,Ctrl+c 退出

watch 参数:-d, --differences        高亮显示变化内容-n, --interval seconds   刷新间隔,默认2秒-t, --no-title           不显示title-e, --errexit            命令执行报错时停止更新,可以按键退出-g, --chgexit            命令输出发生变化时退出-x, --exec               默认将命令交给sh -c ,需要处理引号,通过exec 可以避免额外引号

man 里面给了几个案例,觉得有点意思

watch -d ls -l
watch -d 'ls -l | fgrep joe'
watch -n 5 -d cat /proc/meminfo

tee 输出重定向

tee - read from standard input and write to standard output and files 获取标准输入写入到标准输出和文件

工作中会发现,有时候需要把执行结果重定向到日志文件,但是也需要观察执行情况,开俩窗口?nohub 其实就可以指定输出到文件和启动时输出到窗口,不过 tee 可能是更好的选择。

tee 参数:-a, --append                 追加写入-i, --ignore-interrupts      忽略中断信号--output-error               如果写入报错,做什么操作'warn'            诊断任何写入报错'warn-nopipe'     诊断任何写入报错,除了管道输出'exit'            写入报错时退出'exit-nopipe'     写入报错时退出,除了管道输出

放个自己常用的方式,边看边记录

pidstat -d 5 5 |tee -a pidstat$(date "+%Y%m%d").log


还行

这里记录一些稍微需要花一点点时间的命令,功能相对较复杂一些

cut 内容分割

cut - remove sections from each line of files   用指定的字符方式分割文本

有明显且简单的分隔规律时,cut就能满足文本处理需求

cut -d 字符 -f 第几段 filenamedate "+%D %H:%M:%S"|cut -d ' ' -f 1
01/11/24date "+%D %H:%M:%S"|cut -d ' ' -f 1-2
01/11/24 11:13:23
关于参数 -f 取分段N        取第N段,计数从1开始,超过最大值就是空N-       取第N到最后N-M      取N到M段-M       取第一段到M段

注意:

1)分隔仅支持一个字符,否则报错 cut: the delimiter must be a single character

2)如果用空格分割,空格不会被合并

3)支持文件和重定向的标准输出

iconv 文本编码转换

iconv - convert text from one character encoding to another 文本编码转换

这个命令的参数很少,帮助文档的案例可以直接拿来用

iconv 参数:-l, --list        列出所有已知的字符集编码-o outputfile, --output=outputfile   指定输出到文件-c         遇到无法解析的字符,直接丢弃而不是终止,也会在 -t 的处理选项生效-f from-encoding, --from-code=from-encoding-t to-encoding, --to-code=to-encoding-t 的编码支持指定遇到无法编码的字符的处理//IGNORE        遇到无法编码的字符,丢弃,转换后打印报错//TRANSLIT      无法编码会用近似的字符,没有近似字符用?替换

文档案例测试以及发散: 

echo abc ß α € àḃç | iconv -f UTF-8 -t ASCII//TRANSLIT
abc ss ? EUR abcecho abc ß α € àḃç | iconv -f UTF-8 -t ASCII//IGNORE
abc    
iconv: illegal input sequence at position 22echo abc ß α € àḃç | iconv -f UTF-8 -t ASCII
abc iconv: illegal input sequence at position 4echo abc ß α € àḃç | iconv -f UTF-8 -t ASCII -c
abc
$ file input.txt
input.txt: ISO-8859 text, with CRLF line terminators
$ iconv -f ISO-8859-1 -t ASCII//IGNORE < input.txt -o output.txt
iconv: illegal input sequence at position 112
$ file *.txt
input.txt:  ISO-8859 text, with CRLF line terminators
output.txt: ASCII text, with CRLF line terminators

 ISO-8859 转 GBK 还是 ISO-8859,UTF-8 转其他不行,因为少了libc.mo 未解决,所以还是得了解一下字符集编码才行呐  man charsets 查看字符集编码的介绍

iconv 报错文件不存在排查:

$ file export.log 
export.log: UTF-8 Unicode text
$ iconv -f UTF-8 -t ISO-8859 < export.log
iconv: failed to start conversion processing: No such file or directory
$ strace iconv -f UTF-8 -t ISO-8859 < export.log
...
openat(AT_FDCWD, "/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, "iconv: ", 7iconv: )                  = 7
write(2, "failed to start conversion proce"..., 37failed to start conversion processing) = 37
write(2, ": No such file or directory", 27: No such file or directory) = 27
write(2, "\n", 1
)                       = 1
exit_group(1)                           = ?
+++ exited with 1 +++
$ locale -a |grep en_US.utf8
en_US.utf8

从strace 追踪结果看得出来,这个文件不存在不是输入文件不存在,是编码的文件不存在,报错的文件确实不存在,但是locale 能查询到UTF-8的支持,yum 里面也找不到 libc.mo 的提供软件。没解决,说是要重装glibc ,算了。。。

libc.mo 是一个包含编译好的本地化字符串的文件,它是与 C 库(libc)一起使用的。本地化字符串是特定于语言环境的文本,例如消息、错误消息和用户界面元素的标签。

tr 字符转换与删除

tr - translate or delete characters 转化或删除字符

看帮助文档,tr 支持用集合来处理字符,用处还是不少滴,还有更复杂的用法,建议看看man 

tr 参数:-d, --delete            删除集合1的字符,不转化-s, --squeeze-repeats   字符替换 貌似是默认值例一 把文本小写转大写
$ w | tr -s '[a-z]' '[A-Z]'例二 打印结果去掉斜杠
$ w | tr -d '/'例三 去转义字符
$ echo -e 'a \t b'|tr -d '\t'

sort 排序

 sort - sort lines of text files  对文件的文本按行排序

这个一般搭配nuiq 计数使用,可以在排序后分类和计数

nuiq 计数 

uniq - report or omit repeated lines 报告或省略重复的行

一般搭配sort ,实现分类和统计


有点意思

这部分就记录三剑客,grep  awk sed ,平时工作能用的程度还是不难滴,由于过于强大,这里就简单记录一些平时会用到的,后续发现有意思的方式也会持续补充

grep 文本匹配

grep, egrep, fgrep - print lines matching a pattern 打印匹配模式的行

egrep 就是 grep -E,主要是支持正则表达式的意思

fgrep 就是 grep -F ,主要是用通过字符串列表匹配,由换行符分隔,任何换行符都要匹配

grep 平时主要用来过滤文本,能直接用在文件上面,也能通过管道来过滤,日常工作中使用频率很高;支持正则表达式,让 grep 在文本匹配和过滤处理上自由度极高。正则表达式,grep命令的正则有些不同,随后有记录。

grep 的参数很多,能处理文本,文件/目录,能过滤二进制文件,还能读取块设备和套接字,这里只记录一些可能会用到的,更详细的建议看看man grep

grep 参数:匹配选项:-E, --extended-regexp      正则匹配,扩展规则匹配-F, --fixed-strings        字符串(文本段)匹配-G, --basic-regexp         基础规则匹配 默认匹配控制:-i, --ignore-case                   忽略大小写-v, --invert-match                  反选-e PATTERN, --regexp=PATTERN        使用正则表达式-w, --word-regexp                   单词匹配,完全匹配-x, --line-regexp                   整行匹配,完全匹配输出控制:-c, --count                匹配的数量-m NUM, --max-count=NUM    读取到文本的第NUM行就停止匹配-o, --only-matching        只打印匹配到的内容,而不是过滤到的行-n, --line-number              打印行号-C NUM, -NUM, --context=NUM    打印匹配到的行的前后NUM行-A NUM, --after-context=NUM    打印匹配到的行的后NUM行-B NUM, --before-context=NUM   打印匹配到的行的前NUM行文件和目录:-r, --recursive     可以递归的读取目录下的所有文件,没指定目录就是工作目录-R, --dereference-recursive  在-r 基础上,还将搜索符号链接指向的目录中的文件
grep -v '#'|grep -v '^$'         过滤注释和空白行
grep -i 'error' messages         查找错误日志,忽略大小写
grep -ri '192.168' /etc/         递归读取目录文件内容,并匹配
grep 'hello' *.log               从多个文件中匹配合适的内容
grep "$HOSTNAME" /etc/hosts      从文件中获取匹配用户名的行注意:'' 原样输出,"" 可以取值

注意

1)*.log 是以.log 结尾的内容,.*log 是以log结尾的内容

2)使用管道时,要注意grep 的参数,管道传过来的参数会被认为是文本,也可能是文件

echo 'spring.log'|strace grep sp*.log
有springboot.log:execve("/bin/grep", ["grep", "springboot.log"], [/* 28 vars */]) = 0
没有springboot.log:execve("/bin/grep", ["grep", "sp*.log"], [/* 28 vars */]) = 0

sed 文本替换

awk 文本分割

文本正则表达式

未完待续

相关文章:

  • mysql索引失效场景与mysql优化方式
  • Linux(Centos7)安装 jenkins(jdk11+jenkins2.375),并配置JDK,Maven,Git,GitLab
  • CES 2024丨引领变革,美格智能为智能终端带来生成式AI能力
  • 【Electron】 Vite项目 初始配置 scss
  • 1.5计算机网络的分类
  • 【java八股文】之Java基础篇
  • AUTOSAR从入门到精通-Autosar 中断机制(七)
  • Nginx——日志自动切割
  • 语义分割数据集
  • OpenGauss源码分析-SQL引擎
  • 大模型LLM Agent在 Text2SQL 应用上的实践
  • Docker简介、基本概念和安装
  • GO自研微服务框架-中间件
  • SpringFramework实战指南(一)
  • day3-4 three.js学习笔记
  • [PHP内核探索]PHP中的哈希表
  • 【附node操作实例】redis简明入门系列—字符串类型
  • 【面试系列】之二:关于js原型
  • bearychat的java client
  • Effective Java 笔记(一)
  • IOS评论框不贴底(ios12新bug)
  • LeetCode29.两数相除 JavaScript
  • mac修复ab及siege安装
  • nginx 负载服务器优化
  • oschina
  • React-生命周期杂记
  • Sublime Text 2/3 绑定Eclipse快捷键
  • webpack入门学习手记(二)
  • 当SetTimeout遇到了字符串
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 聚簇索引和非聚簇索引
  • 利用jquery编写加法运算验证码
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 盘点那些不知名却常用的 Git 操作
  • 使用docker-compose进行多节点部署
  • 数组大概知多少
  • 我是如何设计 Upload 上传组件的
  • 智能合约Solidity教程-事件和日志(一)
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • #includecmath
  • (3)nginx 配置(nginx.conf)
  • (52)只出现一次的数字III
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (十) 初识 Docker file
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (转载)CentOS查看系统信息|CentOS查看命令
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .gitignore文件—git忽略文件
  • .md即markdown文件的基本常用编写语法
  • .NET 5种线程安全集合
  • .net 中viewstate的原理和使用
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • .NET框架类在ASP.NET中的使用(2) ——QA
  • ?php echo $logosrc[0];?,如何在一行中显示logo和标题?