디렉터리를 반복적으로 반복하고 디렉터리의 파일에 대해 명령을 실행합니다.

디렉터리를 반복적으로 반복하고 디렉터리의 파일에 대해 명령을 실행합니다.

특정 디렉토리에 포함된 모든 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클래스가 포함되어 있으면 출력 파일의 이름은 입니다 .ca.bsrc/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 재귀 글로브는 유용할 수 있습니다.readdirlstat

# 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가 디컴파일을 수행하지 않으므로 올바른 파일 유형을 확인하는 데 필요한 명령문은 없습니다 .

관련 정보