*nix One-Liner: 확장자별로 파일을 반복적으로 찾아 해당 확장자의 이름을 딴 새 디렉터리에 복사합니다.

*nix One-Liner: 확장자별로 파일을 반복적으로 찾아 해당 확장자의 이름을 딴 새 디렉터리에 복사합니다.

다양한 파일 유형(csv, txt, jpg 등)을 포함하는 많은 디렉터리/하위 디렉터리가 주어지면 어떤 명령이 각 디렉터리를 재귀적으로 검색하고 각 확장명을 따서 명명된 새로운 최상위 디렉터리로 파일을 복사합니다.

한 줄로 이 작업을 수행할 수 있는 방법이 있나요?

답변1

해결책

다음 명령은 현재 디렉터리( .)의 모든 파일을 나열하고 해당 파일의 확장명을 따라 이름이 지정된 디렉터리로 이동합니다 ./OUTPUT.

for file in $(find . -type f) ; do EXTENSION=$(echo "$file" |sed 's/.*\.//g') ; rsync -av $file ./OUTPUT/$EXTENSION/ ; done

위 명령을 실행하기 전에 다음을 수행해야 합니다.

  • 현재 디렉터리에 OUTPUT 디렉터리를 생성합니다( mkdir OUTPUT).
  • 하위 디렉터리에 이름이 일치하는 파일이 없는지 확인하세요.

설명

첫째, 루프는 file의 출력에서 ​​파일을 사용하여 변수를 할당합니다 find . -type f. 명령 의 출력 예 find는 다음과 같습니다.

./a/myfile1.zip
./a/b/adoc1.txt
./a/b/adoc2.txt
./a/b/adoc3.txt
./a/b/adoc4.txt
./a/myfile3.zip
./a/myfile4.zip
./a/myfile2.zip

변수가 EXTENSION생성되고 해당 값은 file마지막 마침표까지 모든 항목이 제거된 변수입니다. 그래서 ./a/myfile1.zip가 될 것입니다 zip.

그런 다음 파일은 파일 확장자 이름을 따서 명명 v된 디렉토리에 동기화됩니다(상세 표시) .OUTPUT

일부 테스트에서 이 명령을 실행한 후 내 파일 트리의 예:

./a
./a/b
./a/b/adoc1.txt
./a/b/adoc2.txt
./a/b/adoc3.txt
./a/b/adoc4.txt
./a/b/c
./a/myfile1.zip
./a/myfile2.zip
./a/myfile3.zip
./a/myfile4.zip
./b
./b/c
./b/c/d
./b/c/file1.txt
./b/c/file2.txt
./b/c/file3.txt
./b/c/file4.txt
./c
./c/d
./c/d/e
./c/d/e/afile1.rar
./c/d/e/afile2.rar
./c/d/e/afile3.rar
./c/d/e/afile4.rar
./OUTPUT
./OUTPUT/rar
./OUTPUT/rar/afile1.rar
./OUTPUT/rar/afile2.rar
./OUTPUT/rar/afile3.rar
./OUTPUT/rar/afile4.rar
./OUTPUT/txt
./OUTPUT/txt/adoc1.txt
./OUTPUT/txt/adoc2.txt
./OUTPUT/txt/adoc3.txt
./OUTPUT/txt/adoc4.txt
./OUTPUT/txt/file1.txt
./OUTPUT/txt/file2.txt
./OUTPUT/txt/file3.txt
./OUTPUT/txt/file4.txt
./OUTPUT/zip
./OUTPUT/zip/myfile1.zip
./OUTPUT/zip/myfile2.zip
./OUTPUT/zip/myfile3.zip
./OUTPUT/zip/myfile4.zip

답변2

이 작업은 매우 간단하게 수행할 수 있습니다.찾다, Alex가 올바르게 제안한 대로: 파일을 검색할 디렉터리가 다음과 같다고 가정합니다./path1/to/some/dir, 파일을 다음 위치로 이동하고 싶습니다./path2/to/other/dir/txt등등,

find /path1/some/dir -type f -exec bash -c 'MYDIR=/path2/to/other/dir${0##*.}; [ -d $MYDIR ] && mv $0 $MYDIR  || mv $0 /path3/to/miscellanea' {} \; 

이 명령은 먼저 모든 파일(-f형) 디렉토리에 포함되어 있습니다./path1/to/some/dir모든 하위 디렉터리를 포함하고 각 파일의 이름을 전달합니다({})를 작은 bash 2개 라이너로 변환하여 먼저 파일 이름에서 확장자를 추출합니다($0bash 내부) 이를 로컬 쉘 변수에 할당합니다.미디르, 그 다음에테스트적합한 디렉토리가 존재하는지(그러한 디렉토리가 없다면 실수를 했을 수도 있음) 디렉토리가 존재하는지(&& ...) 파일을 적절한 디렉터리로 이동합니다. 그렇지 않으면 (||...) 파일을 기본 위치에 배치합니다./path3/to/miscellanea.

위의 내용은 필요한 디렉토리를 이미 생성했다고 가정합니다./path2/to/other/dir/txt등등. 대신 이동 중에 생성하려면 위의 내용을 다음과 같이 수정해야 합니다.

find /path1/some/dir -type f -exec bash -c 'MYDIR=/path2/to/other/dir/${0##*.}; mkdir -p $MYDIR && mv $0 $MYDIR' {} \; 

관련 정보