【问题标题】:How to remove a specific pattern of junk values from a file using awk or sed?如何使用 awk 或 sed 从文件中删除特定模式的垃圾值?
【发布时间】:2016-10-18 05:48:53
【问题描述】:

我的 xml 文件中有两种类型的模式,我想在不影响任何其他有意义的模式的情况下删除它们。

testname="@TEST-Loop${c}- 05030502956 @TEST - verify that the  Handler returns an error indicating â~@~\call barredâ~@~]." enabled="true">

我想改成

testname="@TEST-Loop${c}- 05030502956 @TEST - verify that the  Handler returns an error indicating call barred." enabled="true">

我尝试了下面的代码,但没有成功

awk '{if(match($0,/@TEST.*" enabled="true">$/))
 gsub(/â~@~\\/,"");
 gsub(/â~@~\]/,"");
  print}' $file >> tmp.jmx && mv tmp.jmx $file

【问题讨论】:

  • 有多种方式来表示字符à。您要替换的字节的十六进制转储应该会有所帮助(但是您可能可以自己从那里弄清楚)。
  • 我尝试使用 â 的 ascii 值 131 但没有成功,有什么具体的写法吗?
  • 那将是 \203 八进制但你真的认为它是什么吗?我觉得这不太可能——你真的用十六进制转储或类似的东西检查过吗?更有可能是 0xE2(八进制 \342

标签: awk gsub


【解决方案1】:

您尝试替换的模式看起来像是在某些旧版 8 位编码中查看的损坏的 UTF-8 字符。因为您没有指定是哪种编码,所以我们必须进行大量猜测。

您在询问 Unix 工具,因此此答案假定您正在使用某些 U*x 衍生工具或可以访问本地机器上的类似工具(Cygwin?)

要查找要替换的字符串中的实际字节,您可以执行类似的操作

bash$ grep -o '...~@~...' -m1 "$file" |
> od -Ax -tx1o1
0000000    67  20  e2  7e  40  7e  5c  63  61  0a                        
          147 040 342 176 100 176 134 143 141 012                        
000000a

我将od 用于portability reasons;您可能更喜欢hexdumpxxd 或其他一些工具。输出包括十六进制和八进制,如octal is preferred in Awk,但十六进制在其他编程中无处不在。我在匹配项周围保留了几个上下文字符,以防â 实际上以多字节编码存储在您的示例中,但是在这里,在这个有点推测的示例中,事实证明它由单字节 0xE2 表示(八进制342)。 (这会将identify your terminal encoding 表示为 Latin-1 或一些近亲;可能是 CP125x Windows 编码之一。)

有了这些信息,我们可以继续

awk '{ gsub(/\342~@~./, "") }1' "$file"

替换讨厌的字符序列,或者也许

sed $'s/\xe2~@~.//' "$file"

假设你的 shell 是 Bash 或一些近乎兼容的,它允许你使用 C 风格的字符串 $'...' -- 或者,如果你知道你的 sed 方言支持不可打印字符的特定表示法,你可以使用它,但这更不便携。

(如果您的sed 支持-i 选项,或者您的Awk 支持--inline,您可以就地替换文件,即让脚本用修改后的版本替换文件,而无需重定向或临时文件。同样,这有可移植性问题。)

我想强调的是,我们无法猜测您的编码,因此您的问题最好包含此信息。进一步查看Stack Overflow character-encoding tag wiki,了解此类问题中应包含的内容。

【讨论】:

  • 感谢您的回复。我试过 bash$ grep -o '...~@~...' -m1 "$file" | > od -Ax -tx1o1 但它对我不起作用。我可以使用的任何其他命令。我从未使用过这个 hexdump 或 xxd 。
  • “没用”怎么...? > 是提示符,不是命令的一部分。
  • 我明白了 > od -Ax -tx1o1 000000
  • 那么grep 模式是错误的,文件中的实际字符与该正则表达式不匹配。根据您发布的内容,我只能猜测实际存在哪些字节 - 如果您发布的摘录实际上不具有代表性,我的猜测将是错误的。尝试使用grep -m1 '@TEST-Loop${c}- 05030502956 @TEST ' 之类的方法将整个第一行匹配到od。在最坏的情况下,对整个文件运行od,或者使用带有十六进制转储功能的寻呼机。
  • 哦,如果您收到来自grep 的有关输入编码的警告,请尝试在grep 命令前加上LC_ALL=C——这样整个命令就会类似于LC_ALL=C grep -m 1 '05030502956' "$file" | od -Ax -t1x1o跨度>
猜你喜欢
  • 2013-10-08
  • 1970-01-01
  • 2023-01-26
  • 2011-11-13
  • 1970-01-01
  • 2011-05-25
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多