특정 파일 그룹을 Bash의 특정 폴더 그룹으로 이동

특정 파일 그룹을 Bash의 특정 폴더 그룹으로 이동

예를 들어, 다음과 같은 파일 세트를 이동하려는 경우Chapter1_sectionX를 book/chapter1과 같은 특정 폴더로그리고Chapter2_sectionX에서 책/chapter2로등. 저는 현재 이 접근 방식을 사용하고 있는데 비효율적이라고 생각합니다.

touch chapter{1,2}_section{1..4}.odf
mkdir -p book/chapter{1,2}
mv chapter1_section* book/chapter1
mv chapter2_section* book/chapter2

사용하지 않고 이 작업을 수행하는 더 짧은 방법이 있습니까?~을 위한반지?

답변1

for루프를 사용하지 않습니까 ? Perl 유틸리티( rename일부 배포판에서는 prename또는 file-rename라고도 함 perl-rename)를 사용하여 하위 디렉터리를 만들고 그 안에 파일 이름을 바꿀 수 있습니다. 예를 들어:

$ rename -v 'BEGIN{mkdir "book"};
             if (m/chapter(\d+)/) {
               my $d="book/chapter$1";
               mkdir $d;
               $_ = "$d/$_"
             }' *
chapter1.txt renamed as book/chapter1/chapter1.txt
chapter2.txt renamed as book/chapter2/chapter2.txt
chapter3.txt renamed as book/chapter3/chapter3.txt
chapter4.txt renamed as book/chapter4/chapter4.txt
chapter5.txt renamed as book/chapter5/chapter5.txt

스크립트의 영어 요약:

현재 파일 이름( $_)이 정규 표현식과 일치하는 경우 chapter(\d+)파일 이름에서 장 번호를 추출하고(즉 $1, 정규 표현식의 첫 번째이자 유일한 캡처 그룹임 (\d+)) 해당 장에 대한 디렉터리를 만든 다음 현재 파일의 이름을 다음으로 바꿉니다. 예배 규칙서.

일치하지 않는 파일 이름은 무시됩니다.

renamePerl은 이름 바꾸기 스크립트가 .perl 값을 변경하는 경우에만 파일 이름 바꾸기를 시도합니다 $_. 또한 -f이 옵션을 사용하여 강제로 사용 하지 않는 한 기존 파일 덮어쓰기를 거부합니다 .

Perl 이름 바꾸기를 사용하면 다음을 사용할 수 있습니다.어느스크립트에서 Perl 코드의 이름을 바꿉니다(그러나 pragma가 use strict적용되므로 변수를 선언해야 합니다). 코드가 변경되면 $_파일 이름이 변경됩니다. 그렇지 않다면 그렇지 않습니다.

먼저 테스트 실행을 수행하고 -n이름 바꾸기가 원하는 대로 작동하는지 확인하는 것이 가장 좋습니다(잘못된 일괄 이름 바꾸기에서 복구하는 것은 주요 PITA가 될 수 있음). -n파일 이름을 바꾸지 않고 내용만 표시합니다.회의하다. 자세한 출력을 위해 (위의 것과 같은) -n로 바꾸 -v거나 -n자동 작동을 위해 제거하십시오.

답변2

나는 이 mmv유틸리티가 다음과 같은 작업에 편리하다고 생각합니다.

$ mmv -v 'chapter*_section*.odf' 'book/chapter#1/'
chapter1_section1.odf -> book/chapter1/chapter1_section1.odf : done
chapter1_section2.odf -> book/chapter1/chapter1_section2.odf : done
chapter1_section3.odf -> book/chapter1/chapter1_section3.odf : done
chapter1_section4.odf -> book/chapter1/chapter1_section4.odf : done
chapter2_section1.odf -> book/chapter2/chapter2_section1.odf : done
chapter2_section2.odf -> book/chapter2/chapter2_section2.odf : done
chapter2_section3.odf -> book/chapter2/chapter2_section3.odf : done
chapter2_section4.odf -> book/chapter2/chapter2_section4.odf : done

주다

$ tree book
book
├── chapter1
│   ├── chapter1_section1.odf
│   ├── chapter1_section2.odf
│   ├── chapter1_section3.odf
│   └── chapter1_section4.odf
└── chapter2
    ├── chapter2_section1.odf
    ├── chapter2_section2.odf
    ├── chapter2_section3.odf
    └── chapter2_section4.odf

2 directories, 8 files

답변3

완전성을 기하기 위해 파일 및 대상 디렉터리 이름의 간단한 구조로 인해 다음 find명령은 모든 장 파일을 반복하여 파일 이름에서 이름이 유래된 대상 디렉터리로 이동합니다.

find . -maxdepth 1 -type f -name 'chapter*_section*.odf' -exec bash -c 'f={}; d="book/${f%_*}"; mv "$f" "$d"' \;

이는 일치하는 모든 파일을 (암시적으로) 반복하고 chapter*_section*.odf파일 이름에서 마지막 구성 요소를 제거하여 대상 디렉터리 이름을 파생하는 셸 명령을 실행하고 해당 부분만 효과적으로 유지합니다. 그런 다음 현재 처리된 파일을 해당 하위 디렉터리로 이동합니다._*chapterNbook/

노트

  • -maxdepth 1옵션은 현재 디렉터리를 처리한 후 대상 디렉터리로 이동된 파일에 대해 반복적으로 작업을 수행하는 것이 아니라 현재 디렉터리의 파일에 대해서만 작업을 수행하도록 하는 것과 관련이 있습니다.
  • {}via라는 이름의 셸 명령 에 포함됩니다 .-exec낙담한그러나 악성 코드 삽입 시도를 가정하지 않으면 작동합니다.

관련 정보