使用shell脚本进行Java代码格式化

时间:2021-11-17 00:29:15

I know this is silly but I can't overcome my curiosity. Is it possible to write a shell script to format a piece of java code?

我知道这很傻但我不能克服好奇心。是否可以编写一个shell脚本来格式化一段java代码?

For example, if a user writes in a code:

例如,如果用户在代码中写入:

    public class Super{
    public static void main(String[] args){
    System.out.println("Hello world");
    int a=0;
    if(a==100)
    {
    System.out.println("Hello world");
    }
    else
    {
    System.out.println("Hello world with else");
    }
    }
}

I would like to write a shell script which would make the code like this.

我想写一个shell脚本,它会使代码像这样。

 public class Super
 {
  public static void main(String[] args)
  {
   System.out.println("Hello world");
   int a=0;
   if(a==100){
    System.out.println("Hello world");
   }
   else{
    System.out.println("Hello world with else");
   }
}

To be precise, we should change the formatting of flower brackets. If it is try/catch or control structures we should change it to same line and if it is function/method/class it should come in next line.I have little knowledge about sed and awk which can do this task so easily. Also I know this can be done using eclipse.

确切地说,我们应该改变花括号的格式。如果是try / catch或控制结构,我们应该将它改为同一行,如果它是函数/方法/类,它应该在下一行。我对sed和awk知之甚少,它可以很容易地完成这个任务。我也知道这可以用eclipse完成。

6 个解决方案

#1


Well, I've had some free time on my hands, so I decided to relive my good old linux days :]

好吧,我手上有空闲时间,所以我决定重温我过去的好日子:

After reading a bit about awk and sed, I've decided that it might be better to use both, as it is easier to add indentation in awk and parse strings in sed.

在阅读了一些关于awk和sed的内容之后,我决定使用它们可能会更好,因为在awk中添加缩进并在sed中解析字符串更容易。

Here is the ~/sed_script that formats the source file:

这是格式化源文件的〜/ sed_script:

    # delete indentation
    s/^ \+//g

    # format lines with class
    s/^\(.\+class.\+\) *\({.*\)$/\1\n\2/g

    # format lines with methods
    s/^\(public\|private\)\( \+static\)\?\( \+void\)\? \+\(.\+(.*)\) *\({.*\)$/\1\2\3 \4\n\5/g

    # format lines with other structures
    /^\(if\|else\|for\|while\|case\|do\|try\)\([^{]*\)$/,+1 {   # get lines not containing '{'
                                                            # along with the next line
      /.*{.*/ d             # delete the next line with '{'
      s/\([^{]*\)/\1 {/g    # and add '{' to the first line
    }

And here is the ~/awk_script that adds indentation:

这是添加缩进的〜/ awk_script:

    BEGIN { depth = 0 }
    /}/   { depth = depth - 1 }
          {
              getPrefix(depth)
              print prefix $0
          }
    /{/   { depth = depth + 1 }

          function getPrefix(depth) {
              prefix = ""
              for (i = 0; i < depth; i++) { prefix = prefix "    "}
              return prefix
          }

And you use them like that:

你就这样使用它们:

    > sed -f ~/sed_script ~/file_to_format > ~/.tmp_sed
    > awk -f ~/awk_script ~/.tmp_sed

It is far from proper formatting tool, but I hope it will do OK as a sample script for reference :] Good luck with your learning.

它远非正确的格式化工具,但我希望它可以作为参考示例脚本正常:]祝你学习顺利。

#2


A quick, flawed attempt, but one that works on your sample input:

一个快速,有缺陷的尝试,但一个适用于您的示例输入:

BEGIN {depth = 0;}
/{$/  {depth = depth + 1}
/^}/  {depth = depth - 1}
      {prefix = ""; for (i = 0; i < depth; i++) { prefix = prefix "  "} print prefix $0 ; }

This is an awk script: place it in a file and do

这是一个awk脚本:将它放在一个文件中然后执行

awk -f awk_script_file source_file

Obvious flaws with this include:

明显的缺陷包括:

  • It doesn't catch braceless places where you'd like indentation like

    它没有抓住你想要缩进的无支撑的地方

    if (foo)
      bar();
    
  • It will modify the indent depth based on braces in comments and string literals

    它将根据注释和字符串文字中的大括号修改缩进深度

  • It won't detect { braces followed by comments
  • 它不会检测{括号后跟评论

#3


I think this could be done through a simple 'sed' script. Use 1 variable (bCount) that stores the amount of '{' (opening brackets) - (minus) the amount of '}' (closing brackets) Then I would go through the file and insert 'tabs' according to the actual count of bracets that are used. So

我认为这可以通过一个简单的'sed'脚本来完成。使用1变量(bCount)存储'{'(左括号)的数量 - (减去)'}'的数量(结束括号)然后我将浏览文件并根据实际的数量插入'tabs'使用的支架。所以

public class Super{ //bCount=0
public static void main(String[] args){ //bCount=1
System.out.println("Hello world"); //bCount=2
int a=0; //bCount=2
....and so on

so instert 0 tabs on line 0

所以在0号线上有0个标签

1 tab on line 1

第1行的1个标签

2 tabs on line 3 and 4 and so on...

第3和第4行有2个标签,依此类推......

#4


It is definitely possible... I just don't understand why you would want to spend your time doing it? :] There are enough tools to do that and any decent IDE provides a way to re-format the source code (including Eclipse).

绝对有可能......我只是不明白为什么你会花时间去做呢? :]有足够的工具可以做到这一点,任何体面的IDE都提供了重新格式化源代码(包括Eclipse)的方法。

For example, to format in Eclipse 3.4 (should be similar in other versions) just right click on your project or a file and select "Source > Format" from the menu.

例如,要在Eclipse 3.4中进行格式化(在其他版本中应该类似),只需右键单击项目或文件,然后从菜单中选择“源>格式”。

And if you need to change the way it formats the code, just go to the "Preferences > Java > Code Style > Formatter" and change the template. As far as I know, it is very similar in JDeveloper and NetBeans.

如果您需要更改格式化代码的方式,只需转到“首选项> Java>代码样式>格式化程序”并更改模板。据我所知,它在JDeveloper和NetBeans中非常相似。

#5


Have a look at the CLI for Jalopy. Jalopy is a pretty powerful source formatter.

看看Jalopy的CLI。 Jalopy是一个非常强大的源格式化程序。

#6


Consider using Jindent, which is a "a simple Java Indent Tool using Emacs". It's a free shell script which is a part of the Ptolemy project at Berkeley.

考虑使用Jindent,它是一个“使用Emacs的简单Java缩进工具”。这是一个免费的shell脚本,它是伯克利Ptolemy项目的一部分。

#1


Well, I've had some free time on my hands, so I decided to relive my good old linux days :]

好吧,我手上有空闲时间,所以我决定重温我过去的好日子:

After reading a bit about awk and sed, I've decided that it might be better to use both, as it is easier to add indentation in awk and parse strings in sed.

在阅读了一些关于awk和sed的内容之后,我决定使用它们可能会更好,因为在awk中添加缩进并在sed中解析字符串更容易。

Here is the ~/sed_script that formats the source file:

这是格式化源文件的〜/ sed_script:

    # delete indentation
    s/^ \+//g

    # format lines with class
    s/^\(.\+class.\+\) *\({.*\)$/\1\n\2/g

    # format lines with methods
    s/^\(public\|private\)\( \+static\)\?\( \+void\)\? \+\(.\+(.*)\) *\({.*\)$/\1\2\3 \4\n\5/g

    # format lines with other structures
    /^\(if\|else\|for\|while\|case\|do\|try\)\([^{]*\)$/,+1 {   # get lines not containing '{'
                                                            # along with the next line
      /.*{.*/ d             # delete the next line with '{'
      s/\([^{]*\)/\1 {/g    # and add '{' to the first line
    }

And here is the ~/awk_script that adds indentation:

这是添加缩进的〜/ awk_script:

    BEGIN { depth = 0 }
    /}/   { depth = depth - 1 }
          {
              getPrefix(depth)
              print prefix $0
          }
    /{/   { depth = depth + 1 }

          function getPrefix(depth) {
              prefix = ""
              for (i = 0; i < depth; i++) { prefix = prefix "    "}
              return prefix
          }

And you use them like that:

你就这样使用它们:

    > sed -f ~/sed_script ~/file_to_format > ~/.tmp_sed
    > awk -f ~/awk_script ~/.tmp_sed

It is far from proper formatting tool, but I hope it will do OK as a sample script for reference :] Good luck with your learning.

它远非正确的格式化工具,但我希望它可以作为参考示例脚本正常:]祝你学习顺利。

#2


A quick, flawed attempt, but one that works on your sample input:

一个快速,有缺陷的尝试,但一个适用于您的示例输入:

BEGIN {depth = 0;}
/{$/  {depth = depth + 1}
/^}/  {depth = depth - 1}
      {prefix = ""; for (i = 0; i < depth; i++) { prefix = prefix "  "} print prefix $0 ; }

This is an awk script: place it in a file and do

这是一个awk脚本:将它放在一个文件中然后执行

awk -f awk_script_file source_file

Obvious flaws with this include:

明显的缺陷包括:

  • It doesn't catch braceless places where you'd like indentation like

    它没有抓住你想要缩进的无支撑的地方

    if (foo)
      bar();
    
  • It will modify the indent depth based on braces in comments and string literals

    它将根据注释和字符串文字中的大括号修改缩进深度

  • It won't detect { braces followed by comments
  • 它不会检测{括号后跟评论

#3


I think this could be done through a simple 'sed' script. Use 1 variable (bCount) that stores the amount of '{' (opening brackets) - (minus) the amount of '}' (closing brackets) Then I would go through the file and insert 'tabs' according to the actual count of bracets that are used. So

我认为这可以通过一个简单的'sed'脚本来完成。使用1变量(bCount)存储'{'(左括号)的数量 - (减去)'}'的数量(结束括号)然后我将浏览文件并根据实际的数量插入'tabs'使用的支架。所以

public class Super{ //bCount=0
public static void main(String[] args){ //bCount=1
System.out.println("Hello world"); //bCount=2
int a=0; //bCount=2
....and so on

so instert 0 tabs on line 0

所以在0号线上有0个标签

1 tab on line 1

第1行的1个标签

2 tabs on line 3 and 4 and so on...

第3和第4行有2个标签,依此类推......

#4


It is definitely possible... I just don't understand why you would want to spend your time doing it? :] There are enough tools to do that and any decent IDE provides a way to re-format the source code (including Eclipse).

绝对有可能......我只是不明白为什么你会花时间去做呢? :]有足够的工具可以做到这一点,任何体面的IDE都提供了重新格式化源代码(包括Eclipse)的方法。

For example, to format in Eclipse 3.4 (should be similar in other versions) just right click on your project or a file and select "Source > Format" from the menu.

例如,要在Eclipse 3.4中进行格式化(在其他版本中应该类似),只需右键单击项目或文件,然后从菜单中选择“源>格式”。

And if you need to change the way it formats the code, just go to the "Preferences > Java > Code Style > Formatter" and change the template. As far as I know, it is very similar in JDeveloper and NetBeans.

如果您需要更改格式化代码的方式,只需转到“首选项> Java>代码样式>格式化程序”并更改模板。据我所知,它在JDeveloper和NetBeans中非常相似。

#5


Have a look at the CLI for Jalopy. Jalopy is a pretty powerful source formatter.

看看Jalopy的CLI。 Jalopy是一个非常强大的源格式化程序。

#6


Consider using Jindent, which is a "a simple Java Indent Tool using Emacs". It's a free shell script which is a part of the Ptolemy project at Berkeley.

考虑使用Jindent,它是一个“使用Emacs的简单Java缩进工具”。这是一个免费的shell脚本,它是伯克利Ptolemy项目的一部分。