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

Linux 查找文本中控制字符所在的行

参考资料

  1. ASCIIコード表

目录

  • 一. 业务背景
  • 二. 遇到的问题
  • 三. 分析
    • 3.1 url编码的前置知识
    • 3.2 出现控制字符的`transactionid`分析
    • 3.3 16进制分析
  • 四. 从文本中查找控制字符所在的行
  • 五. 控制字符一览


一. 业务背景

⏹在项目中,业务请求对应着下URL

http://www.test.com/?transactionid=uuid_jksje%0Eiuyh&item=20250635

① 其中transactionid=uuid_jksje%0Eiuyh代表每次交易所产生的订单编号,后台接收到请求之后,会从URL中获取相应的参数,然后将其打印到日志中,最终会产生类似于下面这种日志

140 2024/07/08 12:35:01.547 c1server2	5485	[INFO]	SPLREQUEST	seqNo=11459,eventController=PMT.payinfoforprc.test.search,transactionid=uuid_jksje%0Eiuyh,code=MPLE2002
110	2024/07/08 12:34:56.457 c1server1	5892	[INFO]	MYCODE2005	测试方法被调用。(method=selectSvc_Test_Id param cpId=16xx2 status=OK)	userid=adminUser
150 2024/07/08 12:35:02.231 c1server3	5634	[INFO]	SPLREQUEST	seqNo=11460,eventController=PMT.payinfoforprc.test.search,transactionid=uuid_8934jsklsdf23,code=MPLE1001
120	2024/07/08 12:34:57.235 c1server1	5675	[INFO]	MYCODE2005	测试方法被调用。(method=selectSvc_Test_Id param cpId=16xx2 status=OK)	userid=adminUser

② 服务器中,有一个batch每天夜里执行,从每天的日志中抽取数据做成csv文件,然后传送给其他系统用于数据分析。
做成的csv数据的例子如下所示

20250725,1,,,uuid_8934jsklsdf23,MPLE1001,0
20250819,1,,,uuid_klj0345ljhnhl,MPLE1001,0
20250819,1,,,uuid_672342njkjhjs,MPLE1001,0

二. 遇到的问题

最近接到子系统反馈,部分csv文件存在乱码问题。
使用Linux命令来重现的话,类似于这种情况

⏹正常情况下的csv文件

apluser@ubuntu24:~$ cat <(echo -e "20250635,1,,,uuid_jksje%0Eiuyh,MPLE2002,0\n20250725,1,,,uuid_8934jsklsdf23,MPLE1001,0") | nkf -w
20250635,1,,,uuid_jksje%0Eiuyh,MPLE2002,0
20250725,1,,,uuid_8934jsklsdf23,MPLE1001,0

😓接到反馈的csv文件

apluser@ubuntu24:~$ cat <(echo -e "20250635,1,,,uuid_jksje\x0Eiuyh,MPLE2002,0\n20250725,1,,,uuid_8934jsklsdf23,MPLE1001,0") | nkf -w
20250635,1,,,uuid_jksjeャヘミフナイーーイャー
イーイオーキイオャアャャャ゜クケウエイウャヘミフナアーーアャー

🤔经过调查发现日志文件中的transactionid部分混入了控制字符\x0E,从而导致csv文件中也混入了控制字符\x0E,进而导致乱码问题的发生。也就是说日志中的transactionid的值应该是uuid_jksje%0Eiuyh,但实际上transactionid给变成了uuid_jksje\x0Eiuyh
也就是说transactionid中的%0E居然给转换为\x0E


三. 分析

3.1 url编码的前置知识

⏹以下字符可以在 URL 中直接使用,而无需编码:

  • 英文字母:A-Z、a-z
  • 数字:0-9
  • 部分符号:- _ . ~

⏹任何 非 ASCII 字符(ASCII 码 > 127) 都必须编码,例如:

  • 中国%E4%B8%AD%E5%9B%BD
  • 日本%E6%97%A5%E6%9C%AC
  • 😀 → %F0%9F%98%80

⏹这些字符在 URL 中有特殊含义,如果用于数据内容,则必须编码

字符说明URL 编码
:冒号%3A
/斜杠%2F
?问号%3F
#井号%23
[左方括号%5B
]右方括号%5D
@艾特%40
!感叹号%21
$美元符号%24
&和号%26
'单引号%27
(左括号%28
)右括号%29
*星号%2A
+加号%2B
,逗号%2C
;分号%3B
=等号%3D

⏹例如京东的手机搜索页面的URL
https://search.jd.com/Search?keyword=手机

⏹我们直接通过复制网页的URL,得到的是如下内容
https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA
可以看到 手机 被转换成 %E6%89%8B%E6%9C%BA

⏹通过JavaScript进一步验证

在这里插入图片描述

3.2 出现控制字符的transactionid分析

⏹下图展示了混有控制字符的日志

在这里插入图片描述
⏹通过下面的linux命令可以进行再现

  • echo -e 选项的作用是启用转义序列,让 \n(换行)、\t(制表符)等特殊字符生效。
  • 此处的作用是让\x0E当做转义字符生效
echo -e "seqNo=11459,eventController=PMT.payinfoforprc.test.search,transactionid=uuid_jksje\x0Eiuyh,code=MPLE2002" > 文件名.txt

如果通过JavaScript的decodeURIComponent()函数来进行转换的话,也可以得到相同的效果

decodeURIComponent("uuid_jksje%0Eiuyh")  # uuid_jksje\x0Eiuyh

也就说,后台对下面日志输出的时候,应当将"uuid_jksje%0Eiuyh视为普通的文本,而不是将其解析为uuid_jksje\x0Eiuyh
就算解析为uuid_jksje\x0Eiuyh,也应当将其视为普通文输出到日志中,而不应当将\x0E视作转义字符进行转义。

3.3 16进制分析

将正常的transactionid和混有控制字符的transactionid的日志部分截取出来,放在文本编辑器中,通过16进制进行查看,

  • 正常的transactionid中的%0E所对应的16进制分别是20,30,45
  • 而混有控制字符的transactionid却把普通文本的0E给解析为16进制的0e

🧐文本编辑器使用的是notepadd++,需要下载HEX-Editor插件进行查看
在这里插入图片描述


四. 从文本中查找控制字符所在的行

⏹创建文件

touch TEMP_T01.dat
echo -e "20250635,1,,,uuid_jksje\x0Eiuyh,MPLE2002,0" > TEMP_T01.dat
echo -e "20250725,1,,,uuid_8934jsklsdf23,MPLE1001,0" >> TEMP_T01.dat
echo -e "20250819,1,,,uuid_klj0345ljhnhl,MPLE1001,0" >> TEMP_T01.dat
echo -e "20250635,1,,,uuid_yumkg\x0Eimbt,MPLE2002,0" >> TEMP_T01.dat
echo -e "20250819,1,,,uuid_672342njkjhjs,MPLE1001,0" >> TEMP_T01.dat

⏹使用notepad++查看创建的文件

在这里插入图片描述

  • grep -P "\x0E":精确查找\x0E的控制字符
  • cat -v | grep '\^N':将\x0E的控制字符表示为^N
# 按照指定的控制字符 \x0E 进行查找
$ grep -P "\x0E" TEMP_T01.dat
20250635,1,,,uuid_jksjeiuyh,MPLE2002,0
20250635,1,,,uuid_yumkgimbt,MPLE2002,0

#  cat -v 会将控制字符特殊表示,其中 \x0E 会被表示为 ^N
$ cat -v TEMP_T01.dat | grep '\^N'
20250635,1,,,uuid_jksje^Niuyh,MPLE2002,0
20250635,1,,,uuid_yumkg^Nimbt,MPLE2002,0

⏹按照控制字符的范围进行查找

  • grep -P '[\x00-\x1F]'
  • grep -E '[[:cntrl:]]'
# 按照控制字符的范围进行查找
$ grep -P '[\x00-\x1F]' TEMP_T01.dat
20250635,1,,,uuid_jksjeiuyh,MPLE2002,0
20250635,1,,,uuid_yumkgimbt,MPLE2002,0

# 按照控制字符的范围进行查找
$ grep -E '[[:cntrl:]]' TEMP_T01.dat
20250635,1,,,uuid_jksjeiuyh,MPLE2002,0
20250635,1,,,uuid_yumkgimbt,MPLE2002,0

五. 控制字符一览

10进制16进制code全拼意思
000NULNull空文字
101SOHStart Of Headingヘッダ開始
202STXStart Of Textテキスト開始
303ETXEnd Of Textテキスト終了
404EOTEnd Of Transmission伝送終了
505ENQEnquiry問い合わせ
606ACKAcknowledgement肯定応答
707BELBell警告音を鳴らす
808BSBack Space一文字後退
909HTHorizontal Tabulation水平タブ
100aLF / NLLine Feed / New Line改行
110bVTVertical Tabulation垂直タブ
120cFF / NPForm Feed / New Page改ページ
130dCRCarriage Return行頭復帰
140eSOShift Outシフトアウト(多バイト文字終了)
150fSIShift Inシフトイン(多バイト文字開始)
1610DLEData Link Escapeデータリンク拡張(バイナリ通信開始)
1711DC1Device Control 1装置制御1
1812DC2Device Control 2装置制御2
1913DC3Device Control 3装置制御3
2014DC4Device Control 4装置制御4
2115NAKNegative Acknowledgement否定応答
2216SYNSynchronous idle同期
2317ETBEnd of Transmission Block伝送ブロック終了
2418CANCancel取り消し
2519EMEnd of Medium記録媒体終端
261aSUB / EOFSubstitute / End Of File文字置換 / ファイル終端
271bESCEscapeエスケープ(特殊文字開始)
281cFSFile Separatorファイル区切り
291dGSGroup Separatorグループ区切り
301eRSRecord Separatorレコード区切り
311fUSUnit Separatorユニット区切り
3220SPCSpace空白文字
1277fDELDelete一文字削除
http://www.dtcms.com/a/109316.html

相关文章:

  • 线性欧拉筛
  • AF3 OpenFoldDataset类解读
  • 【面试篇】Kafka
  • 记录学习的第二十天
  • 【LeetCode 题解】数据库:626.换座位
  • Java基础:Logback日志框架
  • C# 与 相机连接
  • 接收灵敏度的基本概念与技术解析
  • 【计网】作业三
  • 2025年2月,美国发布了新版移动灯的安规标准:UL153标准如何办理?
  • MySQL:库表操作
  • CATIA装配体全自动存储解决方案开发实战——基于递归算法的产品结构树批量处理技术
  • 一款非常小的软件,操作起来非常丝滑!
  • 语音识别播报人工智能分类垃圾桶(论文+源码)
  • MySQL 基础使用指南-MySQL登录与远程登录
  • MySQL超全笔记
  • 快速掌握MCP——Spring AI MCP包教包会
  • Pyspark学习二:快速入门基本数据结构
  • 4月3号.
  • Python 函数知识梳理与经典编程题解析
  • FFmpeg录制屏幕和音频
  • 单片机学习之定时器
  • 嵌入式海思Hi3861连接华为物联网平台操作方法
  • Zapier MCP:重塑跨应用自动化协作的技术实践
  • 【Linux】Orin NX + Ubuntu22.04配置国内源
  • 如何实现一个优雅的Go协程池
  • ORION:基于VLM引导动作生成的端到端框架——论文精度
  • 源码分析之Leaflet图层控制控件Control.Layers实现原理
  • 量子计算与人工智能的结合:未来科技的双重革命
  • 人工智能混合编程实践:C++ ONNX进行图像超分重建