【问题标题】:sub except the first pattern that matchsub 除了第一个匹配的模式
【发布时间】:2017-11-23 06:38:54
【问题描述】:

我知道如何在 awk、gred、sed 中进行 sub,但除了第一个匹配项之外不知道如何 sub。我在 doc 中搜索,但找不到正确的命令来执行此操作。 我有一个像这样的简单文件:

tongtha AL_Vcs abcdef
tongtha AL_Vcs abcdef
tongtha AL_Vcs abcdef

tuanngu AL_Ptime HEO
tuanngu AL_Ptime HEO

vuau AL_Ptime E2x
vuau AL_verdi_b E2x
vuau AL_TShell EU2HL

这是我的愿望

tongtha AL_Vcs abcdef
        AL_Vcs abcdef
        AL_Vcs abcdef

tuanngu AL_Ptime HEO
        AL_Ptime HEO

vuau AL_Ptime E2x
     AL_verdi_b E2x
     AL_TShell EU2HL

如果我能把它换成 2 美元,而不仅仅是像这样的 1 美元,那就更好了:

tongtha AL_Vcs abcdef
               abcdef
               abcdef

tuanngu AL_Ptime HEO
                 HEO

vuau AL_Ptime E2x
     AL_verdi_b E2x
     AL_TShell EU2HL

【问题讨论】:

  • 在第二个例子中,sub-in-for-$2 是针对前两个段落而不是第三个段落完成的。是错字吗?
  • 我想保留这 3 美元,否则我以后再数
  • 我指的是第二种情况,你想用$2代替。在前两节中,$2 已被删除。在第三节中,它被保留了下来。特别是,AL_verdi_bAL_TShell 都是 $2 并且它们被保留。
  • 我认为 $2 和 $3 应该使用数组对其进行排序,最小化相似的模式并计算它。但问题是我有很多用户,如果我使用数组并计算它最小化并计算整个文件。

标签: awk sed grep


【解决方案1】:

用空格替换第一列,但不是在第一个匹配项上

$ awk '{save=$1} $1==last{gsub(/./," ",$1)} {last=save} 1' file
tongtha AL_Vcs abcdef
        AL_Vcs abcdef
        AL_Vcs abcdef

tuanngu AL_Ptime HEO
        AL_Ptime HEO

vuau AL_Ptime E2x
     AL_verdi_b E2x
     AL_TShell EU2HL

工作原理

  • save=$1

    这会将第一列的值保存在变量save中。

  • $1==last{gsub(/./," ",$1)}

    如果第一列与变量last相同,那么我们将第一列替换为相同数量的空格。

  • last=save

    这将使用第一列在任何替换之前的值更新变量last

  • 1

    这是 awk 对 print-the-line 的神秘简写。

替换前两列,但不在第一个匹配项上

对前两列执行相同操作:

$ awk '{save=$1} $1==last{gsub(/./," ",$1); gsub(/./," ",$2)} {last=save} 1' file
tongtha AL_Vcs abcdef
               abcdef
               abcdef

tuanngu AL_Ptime HEO
                 HEO

vuau AL_Ptime E2x
                E2x
               EU2HL

【讨论】:

  • 天哪,你救了我的命。非常感谢约翰。我几乎是今天早上才找到答案。
【解决方案2】:

这可能对你有用(GNU sed):

sed -r ':a;N;/^(\S+\s+\S+\s+)(.*\n)\1/{:b;s//\1\n\2\1\n/;h;s/\n.*//;s/./ /g;H;g;s/\n(.*\n).*\n(.*)\n(.*)$/\1\3\2/;ba};/^(\S+\s+)(.*\n)\1/bb;$b;/\n\s*$/b;h;s/\n[^\n]*$//p;g;s/.*\n//;ba' file

sed 脚本一次打印多组行。该脚本首先测试重复的第一个和第二个字段,然后使用通用解决方案将这些字段替换为空格。如果第一个测试失败,则脚本会尝试仅匹配第一个字段,如果成功则使用与上述相同的解决方案。

【讨论】:

    猜你喜欢
    • 2015-05-07
    • 1970-01-01
    • 2014-07-27
    • 2015-08-08
    • 2020-02-09
    • 2020-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多