シェルスクリプトを使用して複数のクラスを持つJavaファイルで基本クラス名を検出する方法は?

シェルスクリプトを使用して複数のクラスを持つJavaファイルで基本クラス名を検出する方法は?

私はスクリプトを作るJavaファイルコネクタcatそして、以下を使用して複数のsedファイル.javaをリンクします。

#!/bin/bash
########################################################################################################################
# This file create a "MainFileName.java.output" file concatenating all java file in this directory.
# Run this script as '$ ./javaFilesConcatenator MainFileName' when "MainFileName.java" contains the main method.
########################################################################################################################

cat *.java | sed -e 's/public class/class/g;s/public interface/interface/g' >$1.java.output
sed -i "s/class $1/public class $1/g" $1.java.output

このスクリプトを実行するには、メインクラス名をユーザーに入力パラメータとして渡します。メインクラスはでなけれpublicばならず、他のクラスはそうではないからです。メインクラスをpublic class ClassName除くすべてを交換しました。class ClassName

メインクラス名を指定せずにメインクラスを検出できるように、スクリプトをより使いやすく変更したいと思います。メインクラスが他のクラスと違うので可能なことだと思います。メソッドが含まれていますmain

importそしてもう一つの要件は、出力ファイルの別の場所から切り取り、文書の先頭にすべての(ig)ステートメントを置く必要があるということです。 (各ファイルには先頭にいくつかのステートメントがありますが、最初はこれらのステートメントをすべてリンクしていない後)。import java.util.Scanner;import

別のオプションの要件は、同様の行をすべて削除しますpackage com.alhelal.texpad;が、単語を含むコメントは削除しないことですpackage

私の要求を聞くことができますか?

ベストアンサー1

スクリプトsedはすべての手順を実行する必要がありますが、テストデータがないためテストできません。

sed '/^[^/]*package/d
     /import  *java\./{p;d;}
     H;/void main()/{g;s/.*\n[[:space:]]*public/& public/;h;}
     $!d;g;s/public class/class/g' *.java

このスクリプトの主な概念:

  • 複数のファイル名をに渡すことができますsed。ファイル名は1行ずつ読み取られます。sedあるファイルと他のファイルがいつ起動されるかはわかりませんが、とにかくここでは必要ありません。
  • 行単位で作業するため、sed後で必要な行を保存するには少しメモリが必要です。これはファイルを並べ替えるために必要です(すべてのインポートは出力の上に表示されます)。このメモリにはsedスペースがあります。クリップボードのように考えてください。スクリプトのすべてのループで新しい行でパターン空間を上書きしても、保持バッファは変更されません。コピーパターンスペースを予約済みスペースとして使用、再hコピー、gまたはその両方を交換できますxHパターンスペースの内容を予約済みスペース(間に改行を含む)に追加し、その逆も同様ですg。したがって、出力の上部にある行はpすぐに印刷(使用)され、他のすべての行は予約済みスペースに追加されます。すべての行の終わりに達すると、予約済みスペースに収集された行を処理できます。
  • 1つを除いてすべてpublic削除する必要があります。私はこれを行うためにトリックを使用します。mainメソッドに会うたびに、最後のクラスがパブリックに保持されるクラスであることがわかるので、これをパブリックとしてマークする必要があります。しかし、どのように?トリック:publicそこに2番目のクラスを追加して取得します。したがって、後ですべてにpublic class fooClass ... public public class thisIsTheMainClass ... public class barClass置き換えると、メインクラスにはまだ1つのプロパティが残ります。 2番目の追加は3行目で行われます(予約済みスペースを使用するにはパターンスペースにコピーしてから再コピーする必要があります)。public classclasspublicpublic
  • 覚えておくべきこと:sedコマンドの前に「アドレス」を付けて、そのアドレスに一致する行に対してのみ実行することができます。アドレスは、行を一致させるためにスラッシュで囲まれた正規表現パターンです。これはスクリプトの最初の3行に使用されます。あるいは、選択されたアドレスが反転され、最後の行を除くすべての項目で選択が実行されるスクリプト$の4行目と同じ行番号または最後の行にすることができます。アドレスの後に角かっこで囲まれたコマンドが来ると、スクリプトの2行目と3行目のように、内部のすべてのコマンドはそのアドレスに対してのみ実行されます。!d{}

スクリプトの詳細:

  • /^[^/]*package/dその単語を含みpackage、前にスラッシュがないすべての行を削除します。これがあなたが望むものであることを願っています。
  • /import *java\./{p;d;}Javaインポートを使用してすべての行を即座に印刷し、追加の処理を停止します。
  • H印刷する代わりに、予約済みスペースに他のすべての行を収集します。これが出力の開始時にすべてのインポートを収集する方法です。
  • /void main()/{g;s/.*\n[[:space:]]*public/& public/;h;}:このmain方法が満たされたら、gこれまでに収集されたラインをパターンスペースに移動します。このコマンドは、s最後に発生した行の先頭を検索して追加します。変更されたバッファを予約済みスペースに再送信publicpublich
  • $!dこれが最後の行でない限り、追加のアクションは必要ありません。
  • g;s/public class/class/g'収集したインポートされていないすべての行をパターン空間に移動し、publicクラスからすべての行を削除します。メインクラスに2番目のクラスを追加すると、publicメインクラスは公開されたままになります。

通常、一部の入力(コメントの識別子またはキーワード)を使用してこれらのスクリプトを中断できます。

おすすめ記事