
我試著從目錄頂部開始反編譯某個目錄中包含的所有 Java 類別。
目錄有許多子目錄,每個子目錄的深度各不相同。
我想要做的是進入每個目錄,如果內容是後綴為 的文件.class
,則運行反編譯命令,這將在同一目錄中創建一個反編譯文件。
我嘗試了以下方法,但他們沒有達到我所追求的目標。
第一種方法是:
for dir in ./*; do ( ( if [[ -d $dir ]]; then cd "$dir"; fi ) && ( for f in "$dir"; do ( if [[ -f $f && $f == *".class"* ]]; then jad "$f"; fi ); done ) ); done
這裡的問題是它不是遞歸的。也許這可以以遞歸的方式進行調整?
第二種方法較簡單,但它輸出頂層目錄中的檔案。雖然這可能沒問題,但不幸的是,我有具有相同名稱但位於不同包中的類,因此該解決方案也不起作用:
find . -type f -name "*.class" | while read filename; do echo $filename; done
可以調整其中一個來實現我想要的嗎?如何將第一個命令轉換為遞歸操作?
答案1
我並不是 100% 確信 JAD 的工作原理,但基於我在此自述文件中找到的訊息,這個find
命令應該給你一個開始:
find . -type f -name '*.class' |\
while IFS= read -r java_class_path
do
java_dirname=$(dirname "${java_class_path}")
jad -sjava -d"${java_dirname}" "${java_class_path}"
done
此-s
選項將設定輸出副檔名.java
,並-d
根據透過.class
找到原始檔案的位置設定檔案輸出的目標目錄find
。解決此類問題的關鍵是要了解您不是第一個想要將命令列輸出輸出到另一個目的地的人。
答案2
jad 支援這個內建的,根據文件。它將為您擴展 glob,包括**
遞歸 glob。因此,請使用引號來保護它們免受 shell 的影響,例如從文件複製的 cmd 範例:
jad -o -r -sjava -dsrc 'tree/**/*.class'
此指令會反編譯位於 的所有子目錄中的所有 .class 文件,並根據類別的套件名稱
tree
在 的子目錄中建立輸出檔 。src
例如,如果檔案tree/a/b/c.class
包含c
套件中的類a.b
,則輸出檔案將具有名稱src/a/b/c.java
。
如果您喜歡它的目錄結構選擇,這幾乎肯定是最好的選擇。我看起來沒有-r
它不會將包結構變成目錄。我不知道你是否可以讓它將文件放在具有目錄結構的文件.java
旁邊。.class
使用find -execdir
在正確的目錄中運行 jad:
# untested
find [more find options] -name '*.class' -execdir jad {} +
這將有效地作用cd
於至少包含一個 的每個目錄.class
,並執行與在那裡運行相同的操作jad *.class
。 (請注意,+
而不是\;
將多個參數分組到一個命令中)。
GNUfind
很強大;讀手冊頁。
或使用 bash 功能:
由於您使用的是 bash,因此可以for dir in ./*
使用 bash 的 globstar 功能進行遞迴。它find
比大目錄樹慢得多,因為 bash 不知道利用返回的檔案類型提示來readdir
避免lstat
每個目錄條目都查看它是否是目錄。但 bash 遞歸 glob 可能很有用。
# untested
shopt -s globstar # put this in your .bashrc if you want it enabled all the time
for dir in ./**/; do
pushd "$dir"
classfiles=( *.class ) # expand the glob into an array
[[ -e $classfiles ]] && # test the first element of the array. Will fail if *.class didn't match anything.
jad *.class
popd "$dir"
done
請注意使用尾部斜線使 glob 僅匹配目錄。
答案3
我想出了一個對我有用的解決方案:
find . -type d | while read dir; do ( if [[ -d $dir ]]; then cd $dir && find . -maxdepth 1 -type f | while read f; do ( jad $f ); done fi ); done
無需if
聲明即可檢查文件類型是否正確,因為如果檔案不是類別文件,jad 將不會執行反編譯。