파일 정렬 및 복사

파일 정렬 및 복사

저는 이곳에 처음 왔으니 양해해 주시기 바랍니다.

수천 개의 파일이 포함된 디렉토리가 있습니다. 파일 이름은 항상 1~2개의 문자로 시작하고 그 뒤에 밑줄 "_" 앞에 4개의 문자가 옵니다. 각 모드의 파일 개수는 다를 수 있으며 파일 이름에서 밑줄 뒤의 부분이 변경됩니다.

견본:

Parentdir:
->AA01_*.pdf 
->AA01_*.html
->AA01_*.txt
...
->ZZ99_*.pdf
->ZZ99_*.html
->ZZ99_*.txt
...
->A001_*.pdf
->A001_*.html
->A001_*.txt
...
->Z999_*.pdf
->Z999_*.html
->Z999_*.txt

파일 이름의 문자만 사용하여 새 디렉터리를 만들고 해당 문자로 시작하는 파일로 채우는 명령을 실행하고 싶습니다. 대상 디렉터리에 같은 이름의 파일(원본 디렉터리의 업데이트된 파일)이 있으면 최신 파일을 유지하고 싶습니다. 그래서:

New dir/files:
->AA
  AA01_*.pdf
  AA01_*.html
  AA01_*.txt
...
->ZZ
  ZZ99_*.pdf
  ZZ99_*.html
  ZZ99_*.txt
...
->A
  A001_*.pdf
  A001_*.html
  A001_*.txt
...
->Z
  Z999_*.pdf
  Z999_*.html
  Z999_*.txt

이것이 달성될 수 있습니까?

감사해요!

답변1

파일 세트를 탐색합니다. 문자 접두어를 선택하세요. 디렉터리를 만들고(필요한 경우) 파일을 해당 디렉터리로 이동합니다.

#!/bin/sh
for item in *
do
    if [ -f "$item" ]
    then
        prefix="$(echo "$item" | sed 's/[^A-Z].*//')"
        echo mkdir -p "$prefix"
        echo mv "$item" "$prefix/"
    fi
done

echo접두사를 제거 mkdir하면 mv만족스러울 때 원하는 대로 작동합니다.

답변2

사용진주 rename유틸리티( 일부 Linux 배포판에서는 prename라고도 함 file-rename) perl-rename:

rename  -n  'if (m/^(\w{1,2}?)(\d{2,}_.*)/) {mkdir $1; $_ = "$1/$1$2"}' *

참고: 이것은 작동합니다오직Perl 기반 이름 바꾸기 유틸리티를 사용하십시오. rename -V(or prename -V또는 or)를 실행하여 file-rename -V설치 여부를 확인할 수 있습니다 perl-rename -V. perl 또는 이 언급되면 File::Rename이는 의 Perl 버전입니다 rename. 그렇지 않으면 완전히 다를 rename수 있습니다util-linux호환되지 않는기능 및 명령줄 옵션. 이것은 것이다아니요util-linux의 이름 바꾸기(또는 다른 버전의 이름 바꾸기 - it)를 사용하십시오.필요펄 이름 바꾸기)

이는 일치하는 각 파일 이름(탐욕적이지 않은 일치)의 처음 한두 개의 "단어" 문자를 디렉토리로 사용한 다음 디렉토리를 생성하고 파일 이름을 디렉토리로 바꿉니다. "단어" 문자( \w)는 다음과 같이 정의됩니다 man perlre.

""단어" 문자 일치(영숫자와 "_", 기타 연결 구두점 및 유니코드 마커)"

이것이 원하는 것이 아니라면 알파벳 문자나 대문자만 사용하는 [[:alpha:]]{1,2}?대신에 패턴을 최적화할 수 있습니다.\w{1,2}?[[:upper:]]{1,2}

\d번호. 당신이 허락하고 싶다면어느밑줄 앞에 문자를 사용하십시오 \w. 또는 [[:alnum:]]알파벳과 숫자만 허용하려면 를 사용하십시오.

전체 패턴(1~2개의 "단어" 문자, 그 뒤에 최소 두 자리 숫자, 그 뒤에 밑줄)과 일치하지 않는 파일 이름은 영향을 받지 않습니다.

참고: -n옵션을 사용하면 연습 실행 작업이 수행됩니다. 내용만 표시됩니다회의하고 있지만 실제로는 하지 않습니다. 요구 사항을 충족한다고 확신하면 제거합니다 (또는 자세한 출력으로 -n교체 ).-v

예를 들어 다음 설정 스크립트가 있다고 가정해 보겠습니다.

#!/bin/bash

for i in A AA Z9 ZZ  ; do
  for j in {01..10} ; do
    touch "$i${j}_.txt"
  done
done

# anomaly
touch A1001_.txt
$ ./setup.sh
$ ls
A01_.txt  A02_.txt  A03_.txt A04_.txt  A05_.txt  A06_.txt  A07_.txt  A08_.txt
A09_.txt A1001_.txt A10_.txt AA01_.txt AA02_.txt AA03_.txt AA04_.txt AA05_.txt
AA06_.txt AA07_.txt AA08_.txt AA09_.txt AA10_.txt setup.sh* Z901_.txt
Z902_.txt Z903_.txt Z904_.txt Z905_.txt Z906_.txt Z907_.txt Z908_.txt
Z909_.txt Z910_.txt ZZ01_.txt ZZ02_.txt ZZ03_.txt ZZ04_.txt ZZ05_.txt
ZZ06_.txt ZZ07_.txt ZZ08_.txt ZZ09_.txt ZZ10_.txt

Perl 이름 바꾸기 스크립트를 실행한 후:

$ rename 'if (m/^(\w{1,2}?)(\d{2,}_.*)/) {mkdir $1; $_ = "$1/$1$2"}' *
$ ls */*
A/A01_.txt   A/A02_.txt   A/A03_.txt   A/A04_.txt   A/A05_.txt A/A06_.txt
A/A07_.txt   A/A08_.txt   A/A09_.txt   A/A1001_.txt A/A10_.txt AA/AA01_.txt
AA/AA02_.txt AA/AA03_.txt AA/AA04_.txt AA/AA05_.txt AA/AA06_.txt
AA/AA07_.txt AA/AA08_.txt AA/AA09_.txt AA/AA10_.txt Z/Z901_.txt
Z/Z902_.txt  Z/Z903_.txt  Z/Z904_.txt  Z/Z905_.txt  Z/Z906_.txt  Z/Z907_.txt
Z/Z908_.txt  Z/Z909_.txt  Z/Z910_.txt ZZ/ZZ01_.txt ZZ/ZZ02_.txt ZZ/ZZ03_.txt
ZZ/ZZ04_.txt ZZ/ZZ05_.txt ZZ/ZZ06_.txt ZZ/ZZ07_.txt ZZ/ZZ08_.txt
ZZ/ZZ09_.txt ZZ/ZZ10_.txt

답변3

포럼에 오신 것을 환영합니다, 지카님!

나는 제안하고 싶다organize- 인내심이 있다면 yaml주어진 위치에서 파일을 검색하고, 이름을 바꾸고, 이동하고, 정렬하고, 이름을 지정할 수 있는 스크립트를 만들 수 있습니다! 나는 그것을 직접 사용합니다. 여러분이 Linux에 얼마나 익숙하신지는 모르겠지만 Git에는 필요한 모든 것을 매우 이해하기 쉬운 방식으로 설명하는 문서가 있습니다.

관련 정보