使用 Bash (sed?) 删除包含特定文本 (regex) 的多行 /* ... */ 样式注释
Posted
技术标签:
【中文标题】使用 Bash (sed?) 删除包含特定文本 (regex) 的多行 /* ... */ 样式注释【英文标题】:Use Bash (sed?) to remove a multiline /* ... */ style comment containing specific text (regex) 【发布时间】:2013-12-01 19:27:59 【问题描述】:我正在寻找一种 bash 解决方案来删除包含现在在 java 类中的 /* ... */ cmets 中被认为是多余的信息的代码 sn-p。
具体来说,之前我们签入代码时,它会自动在类顶部附近添加签入历史的副本:
/* Copyright statement */
/*
* $Log:
* 3 Project1 02/02/2012 19:05:59 Bob Geldof
* Comment 3
* 2 Project1 01/02/2012 15:25:22 Sir Lancelot
* CR-12345
* 1 Project1 22/10/2011 12:15:31 Thomas the Tank Engine
* First implementation of that cool thing
* $
*/
package com.thing.place.blah
...
...
...
我们现在使用不同的工具来更好地显示这些信息,并且由于时间戳、cmets 等方面的差异,在重用代码的项目之间使用代码比较是一件很痛苦的事情。
目前,如果我们处理文件,我们手动删除注释语句和生成语句的 $Log: 关键字,但是我想做的是编写一个脚本来删除所有 java 文件中的它们。我可以使用 bash 脚本在每个 java 文件上运行它,但是在正则表达式中有一些技巧我不知道如何实现。
所以我猜工作流程类似于
-
在文件中查找第一个“$Log:”
查找此文本之前最接近的“/*”
在此文本之后查找最近的“*/”。
删除 "/*" 和 "*/" 之间的所有文本
在不删除之前/之后的任何 cmets 的情况下执行此操作(大多数文件将在上面具有类似格式的版权声明,可能在同一行上带有结束注释和开始注释标记,例如 " ...版权文本结尾*/ /* $Log: ..."
为了做到这一点,我更喜欢与 sed 兼容的正则表达式参数,因为这是我熟悉的使用方法,尽管我会接受你提供的任何东西!此外,如果进行多次传递是有意义的,例如“在开始标签和 $Log: 之间删除”、“在结束标签和 $Log: 之间删除”、“删除 $Log:”,那很好。这是一个一次性的过程,因此速度远不如准确性重要。
非常感谢您的任何建议。 米奇。
【问题讨论】:
好。您错过了工作流程中的一点:0) 您尝试了什么? 我熟悉单行正则表达式查找和替换,但不熟悉在您要查找的特定内容之外使用标记,而对于多行正则表达式则不太熟悉。我开始包含我尝试过的内容,但它使问题变得混乱和困惑,所以我删除了它。 【参考方案1】:以下可能对您有用:
sed '/\/\*/!b;:a;/\*\//!$!N;ba;/$Log:/d' filename
【讨论】:
在我测试过的几个文件中,它很有效!将不得不做进一步的测试,但我已将此标记为正确。不过希望能详细分析一下内容! 在极少数情况下,最后一个 "/*" 标记与公共类等在同一行,在这种情况下,它会清除包括“公共课等......” - 我想知道如何避免这种情况? @MitchKent 我建议您使用示例输入更新问题。 (我个人刚刚从这些文件中手动删除了日志语句,所以没关系)【参考方案2】:#!/usr/local/bin/bash
set -x
find *.java -type f | while read files
do
cat "$files" | \
sed s'@^/\* Copyright statement \*\/@garbage-begin@' | \
sed s'@ \*\/@garbage-end@' \
> "$files"2.java
sed '/garbage-begin/,/garbage-end/d' "$files"2.java > "$files"3.java
mv -v "$files"3.java "$files"
done
【讨论】:
以上是关于使用 Bash (sed?) 删除包含特定文本 (regex) 的多行 /* ... */ 样式注释的主要内容,如果未能解决你的问题,请参考以下文章
从文本文件中删除 Unicode 字符 - sed ,其他 Bash/shell 方法