
특정 디렉토리에 포함된 모든 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
나는 JAD가 정확히 어떻게 작동하는지에 대해 100% 확실하지는 않지만,이 README 파일에서 찾은 정보, 이 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는 이 내장 기능을 지원합니다.,문서에 따르면. 재귀적 글로브를 포함하여 글로브를 확장합니다 **
. 따라서 문서에서 복사한 cmd 예와 같이 따옴표를 사용하여 셸에서 보호합니다.
jad -o -r -sjava -dsrc 'tree/**/*.class'
이 명령은 클래스의 모든 하위 디렉터리에 있는 모든 .class 파일을 디컴파일 하고 클래스의 패키지 이름에 따라
tree
하위 디렉터리에 출력 파일을 생성합니다 .src
예를 들어, 파일에 package 의tree/a/b/c.class
클래스가 포함되어 있으면 출력 파일의 이름은 입니다 .c
a.b
src/a/b/c.java
디렉토리 구조 선택이 마음에 든다면 이것이 거의 확실히 최선의 선택입니다. -r
그것이 없으면 패키지 구조가 디렉토리로 바뀌지 않을 것 같습니다 . 디렉토리 구조의 파일 .java
옆에 파일을 넣을 수 있다면 IDK입니다 ..class
find -execdir
올바른 디렉토리에서 jad를 실행하는 데 사용:
# untested
find [more find options] -name '*.class' -execdir jad {} +
이는 cd
최소한 하나의 가 포함된 모든 디렉토리에 효과적으로 적용되며 그곳에서 .class
실행하는 것과 동일한 작업을 수행합니다 jad *.class
. ( 여러 인수를 하나의 명령으로 그룹화하는 +
대신 참고하세요 \;
)
GNU는 find
강력합니다. 읽다맨 페이지.
또는 bash 기능을 사용하십시오:
bash를 사용하고 있으므로 for dir in ./*
bash의 globstar 기능을 사용하여 재귀적으로 만들 수 있습니다. bash는 디렉터리인지 확인하기 위해 모든 dir 항목을 확인 하지 않아도 되도록 find
에서 반환된 파일 유형 힌트를 활용하는 방법을 모르기 때문에 큰 디렉터리 트리보다 훨씬 느립니다 . 그러나 bash 재귀 글로브는 유용할 수 있습니다.readdir
lstat
# 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가 디컴파일을 수행하지 않으므로 올바른 파일 유형을 확인하는 데 필요한 명령문은 없습니다 .