使用awk,如何匹配后跟单引号的反斜杠字符(是的,这是两个字符)



我有一个日志文件,它是由一个我无法控制的自动化过程定期生成的。在这个日志文件中有很多反斜杠字符(不是'转义')紧跟着一个单引号'的实例。因此它是一个两个字符的文本模式。

我正在寻找将匹配两个字符'模式的awk或sed示例,并将其替换为单个引用'的单个字符模式。在我的环境中,我只能使用bash和标准的gnu-utils;像python或perl这样的花哨的东西在解决这个问题的目标环境中是不可用的。

我尝试:

cat F1.log | awk '{gsub(/\t/,"t")}1' | awk '{gsub(/\'/,"'")}1' > F2.log

cat F1.log | awk '{gsub(/\t/,"t")}1' | sed 's/$(echo "13447")/$(echo 47")/g' > F2.log

边注:第一个内联awk一直是一个长期存在的工作工具,用于将t实例的双字符模式匹配/转换为单字符t。我只是添加了同一个命令的一个新的内联awk实例,并用'替换了t,但是结果在语法上是不正确的。

第一个错误是:-bash: syntax error near unexpected token `)'

第二个错误是:sed: -e expression #1, char 36: Invalid back reference

下面是最近的日志文件中的一个实例,其中有一条适当的数据线连接到od -bc:

0000000 040 040 040 040 040 040 040 040 040 040 040 040 040 040 040 147
g
0000020 160 147 072 040 153 145 171 142 157 170 040 134 047 057 164 155
p   g   :       k   e   y   b   o   x          '   /   t   m
0000040 160 057 056 147 156 165 160 147 057 160 165 142 162 151 156 147
p   /   .   g   n   u   p   g   /   p   u   b   r   i   n   g

我知道我的单/双引号和/或父引号有问题。我已经广泛地搜索了StackOverflow,然后谷歌,没有找到任何解决方案。

非常感谢你的帮助,谢谢。

你不能用单引号做同样的事情,因为你的脚本是用单引号写的:

awk '{gsub(/\'/,"t")}1'
#   ^         ^         ^
#   |        ???        End of string
#   Start of string

您需要通过使用以下模式之一转义单引号:

'stringA'"'"'stringB'
'stringA'''stringB'

或者您可以在模式和替换中键入单个引号的八进制代码:

awk '{gsub(/\47/,"47")}1'

把它们连在一起就得到:

awk '
{
gsub(/\t/,"t")
gsub(/\47/,"47")
}
1
' F1.log > F2.log

需要考虑两点:

  1. 为什么你的数据"损坏"了?首先呢?
  2. 应该添加对所有其他转义序列的支持吗?

try

gawk -c/mawk/nawk 'gsub(/[134][47]/,"f")+1'

gawk (any mode other than -c) 'gsub(/[\][47]/,"f")+1'

Reason being gawk的默认正则表达式引擎的行为相当不同。我已经找出了几个不同的正则表达式可能出错的变体:

gawk  -e '{ print a="11left]13447right" }'
left]'right
--[ CORRECT ]-----------------------------------
sub(/\47/,"f", a)
sub(/\[47]/,"f", a)
sub(/[\][47]/,"f", a)
sub(/[\134][47]/,"f", a)
left]
right
--[ MATCHED WRONG CHAR ]----------------------------
sub(/[134][47]/,"f", a)
left
'right
--[ ERRORED OUT ]—————————————————
sub(/\\134\47/,"f", a)
gawk: cmd. line:1: error: Invalid back reference: /\\\47/
sub(/\134\47/,"f", a)
gawk: cmd. line:1: error: Invalid back reference: /\\47/
sub(/[134]47/,"f", a)
gawk: cmd. line:1: error: Unmatched [, [^, [:, [., or [=: /[]'/
--[ NOTHING MATCHED ]-----------------------------------
sub(/\[47]/,"f", a)
sub(/\\[47]/,"f", a)
sub(/\\\47/,"f", a)
sub(/\\134[47]/,"f", a)
sub(/\\13447/,"f", a)
sub(/\\47/,"f", a)
sub(/\\134[47]/,"f", a)
sub(/\\134\47/,"f", a)
sub(/\\13447/,"f", a)
sub(/\\47/,"f", a)
sub(/\134[47]/,"f", a)
sub(/\13447/,"f", a)
sub(/\134[47]/,"f", a)
sub(/\134\47/,"f", a)
sub(/\13447/,"f", a)
sub(/13447/,"f", a)
left]'right

我在这里找到了一个相关的答案:如何使用sed将单引号(')替换为反斜杠然后单引号(')?

是原始答案的倒数。sed s/"\'"/'/g