私はスクリプトを作る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
またはその両方を交換できますx
。H
パターンスペースの内容を予約済みスペース(間に改行を含む)に追加し、その逆も同様ですg
。したがって、出力の上部にある行はp
すぐに印刷(使用)され、他のすべての行は予約済みスペースに追加されます。すべての行の終わりに達すると、予約済みスペースに収集された行を処理できます。 - 1つを除いてすべて
public
削除する必要があります。私はこれを行うためにトリックを使用します。main
メソッドに会うたびに、最後のクラスがパブリックに保持されるクラスであることがわかるので、これをパブリックとしてマークする必要があります。しかし、どのように?トリック:public
そこに2番目のクラスを追加して取得します。したがって、後ですべてにpublic class fooClass ... public public class thisIsTheMainClass ... public class barClass
置き換えると、メインクラスにはまだ1つのプロパティが残ります。 2番目の追加は3行目で行われます(予約済みスペースを使用するにはパターンスペースにコピーしてから再コピーする必要があります)。public class
class
public
public
- 覚えておくべきこと:
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
最後に発生した行の先頭を検索して追加します。変更されたバッファを予約済みスペースに再送信public
public
h
$!d
これが最後の行でない限り、追加のアクションは必要ありません。g;s/public class/class/g'
収集したインポートされていないすべての行をパターン空間に移動し、public
クラスからすべての行を削除します。メインクラスに2番目のクラスを追加すると、public
メインクラスは公開されたままになります。
通常、一部の入力(コメントの識別子またはキーワード)を使用してこれらのスクリプトを中断できます。