从文件中删除最后一次出现的}

时间:2014-06-03 01:10:49

标签: bash awk sed

我正在尝试使用sed从文件中删除最后一次出现的}。到目前为止,我有这个:

sed -i 's/\(.*\)}/\1/' file

但这会删除与文件末尾一样多的}。所以如果我的文件看起来像这样:

foo
bar
}
}
}

该命令将删除所有3个}字符。我怎样才能将其限制在最后一次出现?

5 个答案:

答案 0 :(得分:7)

有人把我作为解决方案来游戏

sed -i '1h;1!H;$!d;g;s/\(.*\)}/\1/' file

我不确定它和上面的awk解决方案一样好。

答案 1 :(得分:3)

sed是单行简单替换的绝佳工具。对于其他任何事情,只需使用awk,例如使用GNU awk for gensub()和multi-char RS:

$ cat file1
foo
bar
}
}
}
$
$ cat file2
foo
bar
}}}
$
gawk -v RS='^$' -v ORS= '{$0=gensub(/\n?}([^}]*)$/,"\\1","")}1' file1
foo
bar
}
}
$
$ gawk -v RS='^$' -v ORS= '{$0=gensub(/\n?}([^}]*)$/,"\\1","")}1' file2
foo
bar
}}
$

请注意,以上内容将删除最后一个} char和前一个换行符(如果存在),因为我认为这可能是您真正想要的但是如果您只想删除}并留下尾随在这些情况下换行(因为我认为所有当前发布的sed解决方案都会这样做),然后从匹配的RE中删除\n?

$ gawk -v RS='^$' -v ORS= '{$0=gensub(/}([^}]*)$/,"\\1","")}1' file1
foo
bar
}
}

$

如果您想在不手动指定tmp文件的情况下更改原始文件,只需使用-i inplace参数:

$ gawk -i inplace -v RS='^$' -v ORS= '{$0=gensub(/}([^}]*)$/,"\\1","")}1' file1
$ cat file1
foo
bar
}
}

$

答案 2 :(得分:0)

使用缓冲区,您可以直接修改文件:

awk  'BEGIN{file=ARGV[1]}{a[NR]=$0}/}/{skip=NR}END{for(i=1;i<=NR;++i)if(i!=skip)print a[i]>file}' file

答案 3 :(得分:0)

向@jthill索取1行文件问题的备注

sed ':a
$ !{N
    ba
    }
$ s/}\([^}]*\)$/\1/' YourFile

首先需要在缓冲区中加载文件。如果}单独在一行

,则不会删除新行

答案 4 :(得分:0)

当我读到“用最后 ...做某事”时,我认为“反转文件,先用做一些 ...,重新反向文件“

tac file | awk '!seen && /}/ {$0 = gensub(/(.*)}/, "\\\1", 1); seen = 1} 1' | tac