2012-04-03 153 views
0

上周我意外地将我的eclipse项目的所有字符串都外化了。我需要回复这个,我唯一的希望是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?还是有更简单的方法?

+1

所以,我在你的'messages.properties'猜测'VSDataSource.89'是'字符串2'?你想用'messages.properties'中的'VSDataSource.xxx = yyy'中的'yyy'替换'Messages.getString('VSDataSource.xxx')'? – 2012-04-03 23:29:33

+0

@ mathematical.coffee是的。 'key'不需要以'VSDataSource'开头,但对每个字符串都是唯一的。 – 2012-04-03 23:31:08

+0

使用Java?这里有一个类似的东西:http://stackoverflow.com/questions/4766602/un-externalize-strings-from-eclipse-or-intellij。不用在Java文件中创建字符串,您可以浏览所有文件并进行正则表达式搜索和替换。 – 2012-04-03 23:35:58

回答

3

你(GNU sed的?)这可能工作:

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

不错。我会建议-i.bak什么的,只是为了以后再检查。 – 2012-04-04 00:40:49

+0

'OSListActivity.100 =/system/bootmenu/recovery/sbin/tune2fs -j'messages.properties中有很多像这样的条目。所以sed:file-line 52:未知选项为's' – 2012-04-04 00:45:14

+0

只需将s /../../ g'改为某些@@ @ .. @ g'请参阅解决方案:您也可以运行第一部分,并手工检查sed生成的脚本,当快乐保存为'temp.sed'并运行'sed -f temp.sed * .java' – potong 2012-04-04 00:49:42

-1

你不需要编程任何东西。右键单击其中一个已修改的文件,然后选择“替换为>”,“从本地历史记录中上载”。必要时重复。

+0

请阅读问题的第一行。外部化后,我多次修改了代码。用历史来取代几乎是不可能的。 – 2012-04-03 23:40:51

+0

这将是上周你在eclipse项目中意外地将字符串外化的行吗?这只是星期二,你知道...... – phatfingers 2012-04-03 23:45:14

+0

:D这很有趣,我上星期一做了。 – 2012-04-03 23:46:24

2

要重复我的评论的问题 - 我认为Java的问题在Java中的最佳解决:)虽然这可以说是

引起你的Eclipse的帮助问题:)做一个Java程序中,你可以:

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

不是一个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 

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

希望这会有所帮助。

+0

我无法正常工作。 http://pastebin.com/nWMCHEFF – 2012-04-04 00:20:22

+0

你可以从生成的'replace.sh'(和/或你的属性文件,如果可能的话)给我几个(有错误的行)? – 2012-04-04 00:38:08

+0

此外 - 哪个操作系统,bash版本,sed版本?这可能是非常重要的,因为它们中的一些不支持选项(例如'-r'给予'sed'或类似的东西) – 2012-04-04 00:45:16

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的命令行限制。简单地将文件分成块,直到脚本开心。

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

但它应该是一个很好的第一个开始。

+0

“sed:-e表达式#52,字符46:未知选项”s“”http://pastebin.com/bCVrL2Vy – 2012-04-04 00:41:40

+0

我添加了gsub以逃避替换文本中的任何/。那些造成问题。试试看看它是否有效。 – 2012-04-04 03:43:32

+0

有些条目没有被替换,否则你的脚本工作正常。 :) – 2012-04-05 01:23:26