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.mzph.cn/diannao/76627.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python将pdf文件转为图片,如果pdf文件包含多页,将转化的多个图片通过垂直或者水平合并成一张图片

要将PDF文件转换为图片&#xff0c;并将多页PDF垂直合并成一张图片&#xff0c;可以使用PyMuPDF&#xff08;也称为fitz&#xff09;库来读取PDF文件&#xff0c;并使用Pillow库来处理和合并图片。以下是一个示例代码&#xff0c;展示了如何实现这个功能&#xff1a; 首先&…

HarmonyOS 基础组件和基础布局的介绍

1. HarmonyOS 基础组件 1.1 Text 文本组件 Text(this.message)//文本内容.width(200).height(50).margin({ top: 20, left: 20 }).fontSize(30)//字体大小.maxLines(1)// 最大行数.textOverflow({ overflow: TextOverflow.Ellipsis })// 超出显示....fontColor(Color.Black).…

FrameWork基础案例解析(四)

文章目录 单独拉取framework开机与开机动画横屏Android.mk语法单独编译SDKmake 忽略warning单独修改和编译Camera2单独编译Launcher3Android Studio 导入、修改、编译Settings导入 Android Studio 导入、修改、编译Launcher3android 开机默认进入指定Launcher植入自己的apk到系…

基于vscode(GDB)调试ros2节点

一、环境准备 必备vscode插件 1&#xff09;Docker Docker - Visual Studio Marketplace 2&#xff09;Dev Containers Dev Containers - Visual Studio Marketplace 3&#xff09;GDB GDB Debug - Visual Studio Marketplace 二、进去docker镜像 1&#xff09;docker安…

基于springboot的考研成绩查询系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 这些年随着Internet的迅速发展&#xff0c;我们国家和世界都已经进入了互联网大数据时代&#xff0c;计算机网络已经成为了整个社会以及经济发展的巨大动能&#xff0c;考研成绩查询管理事务现在已经成为社会关注的重要内容&#xff0c;因此运用互联网技术来提高考研成绩…

C++:算术运算符

程序员Amin &#x1f648;作者简介&#xff1a;练习时长两年半&#xff0c;全栈up主 &#x1f649;个人主页&#xff1a;程序员Amin &#x1f64a; P   S : 点赞是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全…

PyQt6实例_A股日数据维护工具_使用

目录 前置&#xff1a; 下载预备更新的数据 使用工具更新 用工具下载未复权、前复权、权息数据 在PostgreSQL添加两个数据表 工具&视频 前置&#xff1a; 1 本系列将以 “PyQt6实例_A股日数据维护工具” 开头放置在“PyQt6实例”专栏 2 日数据可在“数据库”专栏&…

REST 方法

FUNCTION ZFM_INTERFACE_LOG. *"---------------------------------------------------------------------- *"*"本地接口&#xff1a; *" IMPORTING *" REFERENCE(IV_DSTART) TYPE EDI_UPDDAT *"---------------------------------------…

QT 中的元对象系统(五):QMetaObject::invokeMethod的使用和实现原理

目录 1.简介 2.原理概述 3.实现分析 3.1.通过方法名调用方法的实现分析 3.2.通过可调用对象调用方法的实现分析 4.使用场景 5.总结 1.简介 QMetaObject::invokeMethod 是 Qt 框架中的一个静态方法&#xff0c;用于在运行时调用对象的成员函数。这个方法提供了一种动态调…

Unity3D开发AI桌面精灵/宠物系列 【三】 语音识别 ASR 技术、语音转文本多平台 - 支持科大讯飞、百度等 C# 开发

Unity3D 交互式AI桌面宠物开发系列【三】ASR 语音识别 该系列主要介绍怎么制作AI桌面宠物的流程&#xff0c;我会从项目开始创建初期到最终可以和AI宠物进行交互为止&#xff0c;项目已经开发完成&#xff0c;我会仔细梳理一下流程&#xff0c;分步讲解。 这篇文章主要讲有关于…

Java 状态模式 详解

状态模式详解 一、状态模式概述 状态模式(State Pattern)是一种行为型设计模式&#xff0c;它允许一个对象在其内部状态改变时改变它的行为&#xff0c;使对象看起来似乎修改了它的类。 核心特点 状态封装&#xff1a;将每个状态的行为封装到独立的类中状态转换&#xff1a…

Nginx 配置 HTTPS 与 WSS 完整指南

Nginx 配置 HTTPS 与 WSS 完整指南 本教程将手把手教你如何为网站配置 HTTPS 加密访问&#xff0c;并通过反向代理实现安全的 WebSocket&#xff08;WSS&#xff09;通信。以 https://www.zhegepai.cn 域名为例&#xff0c;完整流程约需 30 分钟完成。 一、前置准备 1.1 域名…

双向链表的理解

背景 代码中经常会出现双向链表&#xff0c;对于双向链表的插入和删除有对应的API函数接口&#xff0c;但直观的图表更容易理解&#xff0c;所以本文会对rt-thread内核代码中提供的双向链表的一些API函数操作进行绘图&#xff0c;方便后续随时查看。 代码块 rt-thread中提供…

大文件上传源码,支持单个大文件与多个大文件

大文件上传源码&#xff0c;支持单个大文件与多个大文件 Ⅰ 思路Ⅱ 具体代码前端--单个大文件前端--多个大文件前端接口后端 Ⅰ 思路 具体思路请参考我之前的文章&#xff0c;这里分享的是上传流程与源码 https://blog.csdn.net/sugerfle/article/details/130829022 Ⅱ 具体代码…

Unity中的静态合批使用整理

静态批处理是一种绘制调用批处理方法&#xff0c;它组合不移动的网格以减少绘制调用。它将组合的网格转换为世界空间&#xff0c;并为它们构建一个共享顶点和索引缓冲区。然后&#xff0c;对于可见网格&#xff0c;Unity 会执行一系列简单的绘制调用&#xff0c;每个调用之间几…

【机器学习中的基本术语:特征、样本、训练集、测试集、监督/无监督学习】

机器学习基本术语详解 1. 特征&#xff08;Feature&#xff09; 定义&#xff1a;数据的属性或变量&#xff0c;用于描述样本的某个方面。作用&#xff1a;模型通过学习特征与目标之间的关系进行预测。示例&#xff1a; 预测房价时&#xff0c;特征可以是 面积、地段、房龄。…

C++学习之路:指针基础

目录 指针介绍与基本用法双重指针函数指针空指针与野指针函数参数的指针传递最后 指针一般在C/C语言学习的后期接触&#xff0c;这样就导致指针给新手一种高深莫测、难以掌握的刻板印象。但实际上指针的使用很简单&#xff0c;并且还能够极大的提高程序的灵活性&#xff0c;帮助…

【服务日志链路追踪】

MDCInheritableThreadLocal和spring cloud sleuth 在微服务架构中&#xff0c;日志链路追踪&#xff08;Logback Distributed Tracing&#xff09; 是一个关键需求&#xff0c;主要用于跟踪请求在不同服务间的调用链路&#xff0c;便于排查问题。常见的实现方案有两种&#x…

Kafka+Zookeeper从docker部署到spring boot使用完整教程

文章目录 一、Kafka1.Kafka核心介绍&#xff1a;​核心架构​核心特性​典型应用 2.Kafka对 ZooKeeper 的依赖&#xff1a;3.去 ZooKeeper 的演进之路&#xff1a;注&#xff1a;&#xff08;本文采用ZooKeeper3.8 Kafka2.8.1&#xff09; 二、Zookeeper1.核心架构与特性2.典型…

JUC系列JMM学习之随笔

JUC: JUC 是 Java 并发编程的核心工具包,全称为 Java Util Concurrent,是 java.util.concurrent 包及其子包的简称。它提供了一套强大且高效的并发编程工具,用于简化多线程开发并提高性能。 CPU核心数和线程数的关系:1核处理1线程(同一时间单次) CPU内核结构: 工作内…