여러 모듈이 포함된 대규모 Java 프로젝트가 있는데, 프로젝트 파일은 module1
, module2
... 폴더에 있습니다. 이제 디렉터리를 maven/gradle 친화적 모드로 재구성하여 모든 .java 파일이 폴더에 있고 MODULE_NAME\src\main\java\
모든 비 java 파일이 MODULE_NAME\src\main\resources\
폴더에 있도록 하려고 합니다.
cd /home/MYUSER/oldproject
find . -type f -name *.java -print | exec `sed 's:^./\([a-z0-9\-]*\)/\(.*\)/\([a-zA-Z0-9_-]*.java\):mkdir -p /home/MYUSER/project/\1/src/main/java/\2:'`
이 명령은 필요한 폴더(패키지)를 잘 생성하지만 실행하면
find . -type f -name *.java -print | exec `sed 's:^./\([a-z0-9\-]*\)/\(.*\)/\([a-zA-Z0-9_-]*.java\):mv \0 /home/MYUSER/project/\1/src/main/java/\2/:'`
메시지 오류가 많이 발생합니다.
mv: cannot stat 'mv': No such file or directory
mv: cannot stat '/home/MYUSER/project/module1/src/main/java/com/apackage/': No such file or directory
패키지가 존재하는 동안 많은 파일이 단순히 관련 없는 모듈로 이동되었습니다.
누구든지 이 문제를 해결하도록 도와줄 수 있나요?
정규식으로 좀 더 명확하게 표현하자면 s:^./\([a-z0-9\-]*\)/\(.*\)/\([a-zA-Z0-9_-]*.java\)
, 첫 번째 Capture( \([a-z0-9\-]*\)
)는 모듈을 가져오고, 두 번째 Capture( \(.*\)
)는 Java 패키지를 가져오고, 세 번째 Capture( \([a-zA-Z0-9_-]*.java\)
)는 클래스 이름을 가져옵니다.
파일 예시 목록:
./oldproject/module1/com/mycompany/dir1/dir2/dir3/Class1.java
./oldproject/module1/com/mycompany/dir1/dir4/Class2.java
./oldproject/module2/com/mycompany/dir5/dir6/dir7/dir8/Class3.java
./oldproject/module2/com/mycompany/dir5/dir6/File1.txt
./oldproject/module2/META-INF/File2.txt
나는 그들이 그러기를 원한다
./project/module1/src/main/java/com/mycompany/dir1/dir2/dir3/Class1.java
./project/module1/src/main/java/com/mycompany/dir1/dir4/Class2.java
./project/module2/src/main/java/com/mycompany/dir5/dir6/dir7/dir8/Class3.java
./project/module2/src/main/resources/com/mycompany/dir5/dir6/File1.txt
./project/module2/src/main/resources/META-INF/File2.txt
모듈 이름 regex \([a-z0-9\-]*\)
패키지 이름(중간 폴더) regex \([a-z0-9_]*\)
(그러나 여러 개의 중첩 패키지일 수 있음) 클래스 이름 regex\([a-zA-Z0-9_-]*.java\)
sed
업데이트: 명령을 생성하는 것이 모든 명령을 연결하는 것 같습니다 mv
. 이것이 문제입니다(그들 사이에 새 줄이 없음). 따라서 exec가 각 sed의 출력을 하나씩 실행하지 않는 것처럼 보입니다. 그래서 질문은 mkdir이 어떻게 작동하는가입니다.
답변1
이 시도:
cd /home/MYUSER/
shopt -s globstar # required in bash for recursion, not needed by zsh
for f in **/*.java; do
nf=$(sed 's:^oldproject/\([a-z0-9\-]*\)/\(.*\)/\([a-zA-Z0-9_-]*.java\):project/\1/src/main/java/\2/\3:' <<< "$f")
echo install -D "$f" "$nf"
echo rm -f "$f"
done
# clean empty dirs
#find . -type d -exec rmdir {} + 2>/dev/null
#rm -rf oldproject # or this one if it's what you need
echo
시도가 만족스러우면 이 두 명령을 제거하십시오.
install -D source_file dest_file
필요한 전체 디렉토리 구조를 투명하게 생성합니다 mkdir -p
.
산출
install -D oldproject/module1/com/mycompany/dir1/dir2/dir3/Class1.java project/module1/src/main/java/com/mycompany/dir1/dir2/dir3/Class1.java
rm -f oldproject/module1/com/mycompany/dir1/dir2/dir3/Class1.java
install -D oldproject/module1/com/mycompany/dir1/dir4/Class2.java project/module1/src/main/java/com/mycompany/dir1/dir4/Class2.java
rm -f oldproject/module1/com/mycompany/dir1/dir4/Class2.java
install -D oldproject/module2/com/mycompany/dir5/dir6/dir7/dir8/Class3.java project/module2/src/main/java/com/mycompany/dir5/dir6/dir7/dir8/Class3.java
rm -f oldproject/module2/com/mycompany/dir5/dir6/dir7/dir8/Class3.java