如何删除除最后一次出现的字符串之外的所有字符串?

如何删除除最后一次出现的字符串之外的所有字符串?

我正在尝试删除2016/01/30 14:52:51:除最后一个之外的所有出现的情况。我试过这个:

awk '{gsub(//,"2016/01/30 14:52:51: ",$1);print}'

将除了最后一次出现的所有内容替换为空,但这只是重复了2016/01/30 14:52:51:4 次,数字略有不同。

答案1

该脚本存在多个问题,而且问题陈述需要一些澄清:

  • gsub 调用的正则表达式参数错误
  • 更新对(语句中使用的值)$1没有影响$0print
  • OP 没有澄清其意图是使行上的最后一个事件保持不变,还是仅包含日期的最后一行(后者更有可能)。

这是一个包含这些修复和假设的脚本:

#!/bin/sh
awk '
BEGIN { row=0; fixup = -1; }
{
    before[row] = $0;
    gsub("2016/01/30 14:52:51: ", "", $0);
    if ( $0 != before[row] ) {
            fixup = row;
    }
    after[row++] = $0;
}
END {
    if (fixup >= 0) {
            after[fixup] = before[fixup];
    }
    for (n = 0; n < row; ++n) {
            print after[n];
    }
}
'

(使用两个数组效率较低,但与不使用before数组相比,可以更轻松地进行进一步修改)。

我通过创建一个输入文件(foo.in)来测试这一点:

1awk '{gsub(//,"2016/01/30 14:52:51: ",$1);print}'
2awk '{gsub(//,"2016/01/30 14:52:51: ",$1);print}'
3awk '{gsub(//,"2016/01/30 14:52:51: ",$1);print}'
4awk '{gsub(//,"2016/01/30 14:52:51: ",$1);print}'

并像这样运行脚本:

./foo <foo.in

并得到了

1awk '{gsub(//,"",$1);print}'
2awk '{gsub(//,"",$1);print}'
3awk '{gsub(//,"",$1);print}'
4awk '{gsub(//,"2016/01/30 14:52:51: ",$1);print}'

答案2

我的贡献是一个符合 POSIX 标准的 ed 替代 Thomas Dickey 的 AWK;它做出相同的假设:

printf '%s\n' '1;?2016/01/30 14:52:51: ?' '1,.-g//s///' w q | ed filename

ed 向后遍历文件的能力使这项任务很快就能完成。

相关内容