【问题标题】:Matching special characters in with sed用 sed 匹配特殊字符
【发布时间】:2015-05-28 14:18:55
【问题描述】:

我有一个文件,其行如下。我的目标是用 ** 掩盖姓名、出生日期、电子邮件地址、邮寄地址、住宅地址、电话号码、其他电话号码等字段的值。棘手的部分是,在下一个字段开始之前可能没有可预测的文本长度。例如,城市在哪里结束,州在哪里开始......所以也许使用 * 来知道终点?我正在使用 .sed 文件并针对此日志文件运行它。 “|”也是文件的一部分。它基本上是一个输出到日志文件中的屏幕

    -------------------------------------------------------------------------- --------
    | XXX XX Requested function key not allocated.                                  |
    |     ***** System *****                                                         |
    |                           - Maintain  -              11:55 AM                  |
    | < 1 more  P                                                           3 more > |
    | *Action (A,D,M): _                                                                      |
    |  Office Number: 14                                                             |
    | Case ID:    XXXXXXXXX    Email Address: ___________________________________    |
    | Name: TWENTYFIFTEE MAYSEVEN          DOB: 11111950  *Correspondence Lang: _    |
    |                            Street One                    Street Two            |
    | Mailing Address....: 7 MAY____________________    _________________________    |
    | City...............: DALLAS_________ *State: TX Zip Code: 75062 - ____         |
    |                                                                                |
    | Residential Address: 7 MAY____________________    _________________________    |
    | City...............: DALLAS_________ *State: TX Zip Code: 75062 - ____         |
    | Phone Number...:( ___ ) ___ - ____    Other Phone Number:( ___ ) ___ - ____    |
    | Authorized Rep                     Last      TTL   First   MI                  |
    |                              Name........: ____________ ___ _________ _        |
    | Authorized Representative Phone Number: ( ___ ) ___ - ____                     |
    | Last Updt Dttm......: 05/07/2015 11:55:01 AM   Last Update User: JU14          |
    |                         XXXXXX               XXXXXX                            |
    |                                                                                |
    ----------------------------------------------------------------------------------

【问题讨论】:

  • 结构是否总是相同的(相同的字段顺序和位置)?当您指定文本的长度可能无法预测时,是否可以多行,只是在内容结束或内容长度之后开始的下一个字段是未知的并使用空格 i> 直到下一个字段名称(即在 screen 中的同一位置)?
  • @NeronLeVelu 多行是不可能的。只需找到合适的标签并替换值即可。下面 Martin Konecny 建议的选项是一个可行的选项,但无论出于何种原因,我都无法使其正常工作。

标签: regex sed


【解决方案1】:

使用分隔符逐个选项

for Balise in '| Name: <-> DOB:' ' DOB: <->   |' ' Email Address: <->   |' 
 do
   sed ":cycle
      s/\(${Balise%<->*}[*]*\)[^*]\(.*${Balise#*<->}\)/\1*\2/
      t cycle" YourFile > TempFile
   mv TempFile YourFile
 done
  • 每次更改使用 2 个分隔符。每个更改定界符在for in 循环条目中通过由第一个定界符后跟&lt;-&gt; 和结束定界符组成的字符串定义。
    • 我在这段代码中添加了 3 个示例
    • 您可以使用其他字符序列作为分隔符之间的分隔符,但结果是调整 sed 部分(实际上是 ${Balise...} 中的 &lt;-&gt;
  • sed 将通过* 递归地更改两个分隔符之间的字符
  • 您可以在 GNU sed 中使用 -i 选项来代替此处用于任何版本的临时文件

【讨论】:

    【解决方案2】:

    所以也许用 * 来知道终点?

    我不确定这是否是一个好方法。似乎并非所有字段都后跟*,这不包括字段值中包含* 的情况。

    假设您可以用* 字符替换整个字段,我会将其分解为多个sed 命令(每个要替换的字段一个)。

    这也需要一些手工工作;在这里,我们将几乎任何类型的 30 个字符 . 替换为 30 个 * 字符,因为这就是“名称”值字段的字符数。

    name_len=30
    sed -r "s/(Name: ).{,$name_len}/\1$(printf '*%.0s' {1..$name_len})/g"
    

    这对你第 9 行的影响是

    | Name: ****************************** DOB: 11111950  *Correspondence Lang: _    |
    

    【讨论】:

    • 谢谢@Martin Konecny。我会试一试,并随时通知您
    • 我收到以下错误:`sed: 1: test.sed: extra characters at the end of n command`
    • 我在 Mac 上运行它。所以我用 -i 选项尝试了它并得到“未终止的替代模式”
    • 如果你这样做cat filename | sed -r "s/(Name: ).{,$name_len}/\1$(printf '*%.0s' {1..$name_len})/g",输出是什么?
    • 我得到“sed: 非法选项 -- r”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 1970-01-01
    • 2011-05-17
    • 1970-01-01
    相关资源
    最近更新 更多