用sed搜索并替换

时间:2012-04-03 23:25:22

标签: java sed

上周我意外地将我的日食项目的所有字符串外化。我需要恢复这个,我唯一的希望就是sed。我试图创建脚本但是可怜失败因为我是sed的新手,这将是一个非常复杂的操作。我需要做的是:

class.java文件中的字符串目前采用以下格式(方法)Messages.getString(<key>)。示例:

    if (new File(DataSource.DEFAULT_VS_PATH).exists()) {
        for (int i = 1; i <= c; i++) {
            if (!new File(DataSource.DEFAULT_VS_PATH
                    + Messages.getString("VSDataSource.89") + i).exists()) { //$NON-NLS-1$
                getnewvfspath = DataSource.DEFAULT_VS_PATH
                        + Messages.getString("VSDataSource.90") + i; //$NON-NLS-1$
                break;
            }
        }
    }

键和匹配的字符串在messages.properties文件中,格式如下。

VSDataSource.92=No of rows in db = 
VSDataSource.93=Verifying db entry : 
VSDataSource.94=DB is open
VSDataSource.95=DB is closed
VSDataSource.96=Invalid db entry for 
VSDataSource.97=\ removed.
key=string

所以我需要以这种格式返回java文件:

    if (new File(DataSource.DEFAULT_VS_PATH).exists()) {
        for (int i = 1; i <= c; i++) {
            if (!new File(DataSource.DEFAULT_VS_PATH
                    + "String 2" + i).exists()) { //$NON-NLS-1$
                getnewvfspath = DataSource.DEFAULT_VS_PATH
                        + "String 1" + i; //$NON-NLS-1$
                break;
            }
        }
    }

如何使用sed完成此操作?或者有更简单的方法吗?

4 个答案:

答案 0 :(得分:3)

这可能适合你(GNU sed?):

sed 's|^\([^=]*\)=\(.*\)|s@Messages.getString("\1")@"\2"@g|;s/\\/\\\\/g' messages.properties |
sed -i -f - *.java

答案 1 :(得分:2)

重复我对这个问题的评论 - 我认为Java问题最好用Java解决:)虽然这可能是由你引起的Eclipse帮助问题:)

创建一个Java程序,您可以:

  • 阅读属性,
  • 遍历所有项目.java文件,
  • 对于每个文件:
    • 逐行阅读每个文件
    • 使用正则表达式替换所有字符串,从加载的属性中键入
    • 完成阅读所有行后保存。

不是2分钟的工作,但很容易。

但如果你真的想用sed;)

mkt.sh

$ cat mkt.sh
# Test structure
rm -rf a b
mkdir a
mkdir b
cat > a/A.java <<EOF
my plans for replace
this will be left alone 
EOF
cat > b/B.java <<EOF
propery ginger
broccoli tomato potato
EOF

display() {
  for i in a/A.java b/B.java; do
    echo --- $i
    cat $i
  done
}

display

# Prop change
echo 'echo --- Replacing in: $1' > replace.sh
sed -r 's/([^=]+)=(.+)/sed -i '\''s#\1#\2#'\'' $1/' sample.properties >> replace.sh
chmod u+x replace.sh

# Replace
find -type f -name "*.java"|xargs -n1 ./replace.sh

# Test
display

执行命令

$ ./mkt.sh 
--- a/A.java
my plans for replace
this will be left alone 
--- b/B.java
propery ginger
broccoli tomato potato
--- Replacing in: ./a/A.java
--- Replacing in: ./b/B.java
--- a/A.java
my plans for world domination
this will be left alone 
--- b/B.java
propery ginger
steak tomato potato

这应该可以在你的.java文件上正常工作,但是执行之前要复制;)如果字符串中有#,你会遇到一些问题,但你可以通过从属性文件中删除它们,进行替换,将它们带回并更改此行:

sed -r 's/([^=]+)=(.+)/sed -i '\''s#\1#\2#'\'' $1/' sample.properties >> replace.sh

到例如:

sed -r 's/([^=]+)=(.+)/sed -i '\''s+\1+\2+'\'' $1/' sample.properties >> replace.sh

其中+不是剩余字符。有点麻烦,但是......

希望这有帮助。

答案 2 :(得分:2)

makesed.awk:

BEGIN {
    FS="=";
    print "for i in *.java"
    print "do"
    print "sed \\"
}

{
    msg = "Messages.getString(\"" $1 "\")";
    gsub("/","\\/",$2);
    print "-e 's/" msg "/\"" $2 "\"/g' \\"
}

END {
    print "$i > $$"
    print "mv $$ $i"
    print "done" 
}

执行命令

awk -f makesed.awk yourpropertiesfile.dat > process.sh

这为您提供了一个shell脚本:

for i in *.java
do
sed \
-e 's/Messages.getString("VSDataSource.92")/"No of rows in db "/g' \
-e 's/Messages.getString("VSDataSource.93")/"Verifying db entry : "/g' \
-e 's/Messages.getString("VSDataSource.94")/"DB is open"/g' \
-e 's/Messages.getString("VSDataSource.95")/"DB is closed"/g' \
-e 's/Messages.getString("VSDataSource.96")/"Invalid db entry for "/g' \
-e 's/Messages.getString("VSDataSource.97")/"\ removed."/g' \
$i > $$
mv $$ $i
done

然后进入各自的Java目录并运行:

sh process.sh

这将“修复”该目录中的所有java文件。

如果你的属性文件很长,你很可能会使用sed运行到命令行限制。只需将文件拆分为块,直到脚本满意为止。

显然这不适用于任何转义字符,如果你的消息中有“=”,你也会遭受一些痛苦。如果你傻到能够在没有备份的代码上运行它,那么你当然应该得到任何发生在你身上的事情。

但它应该是一个良好的开端。

答案 3 :(得分:-1)

您无需编程任何内容。右键单击其中一个已修改的文件,然后选择“替换为&gt;”,“从本地历史记录中删除”。根据需要重复。