REGEX 기반 파일을 올바른 이름의 디렉터리로 안전하게 이동하고 이름을 바꾸는 방법

REGEX 기반 파일을 올바른 이름의 디렉터리로 안전하게 이동하고 이름을 바꾸는 방법

큰 드라이브에는 각각 이름은 다르지만 정규식이 포함된 수백 개의 파일이 있습니다. 각각은 난수를 추가하고 경우에 따라 문자를 추가합니다.

예를 들어 "television"이라는 단어의 변형된 이름을 가진 30개의 파일과 "lightbulb"의 변형된 이름을 가진 50개의 파일이 있습니다.

문제는 몇 년 전에 이름을 생성하기 위해 스크립트를 구현할 때 사용했던 잘못된 코딩 방식으로 인해 일관성이 매우 떨어진다는 것입니다.

  • TV139443.png
  • TV244904.png
  • televisio097798.png
  • elevisio984882.png
  • _televisi90890890.png
  • TV-911181.png

당신은 이해했습니다. 이 모드는 "TV", "전구", "자동차" 등 모든 파일 "범주"에 대해 작동합니다. 다행스럽게도 각 파일 이름에는 다른 카테고리(고양이 12마리)에서 반복되지 않는 최소 5개의 일관된 문자가 있습니다.

내가 달성하고 싶은 것은 혼합 폴더를 반복적으로 반복하고 올바른 전체 제목과 추가된 생성 날짜로 각 파일의 이름을 바꾸고 해당 폴더로 이동하는 것입니다.

약간 다음과 같습니다.

   case : regex("levis"):
rename to Television-($creation_date).($extension)
mv to ~/Categories/Television/
break;
    case : regex("ghtbu"):
rename to Lightbulb-($creation_date).($extension)
mv to ~/Categories/Lightbulbs/
break;

분명히 이것은 올바른 코드가 아닙니다. 단지 아이디어를 설명하기 위한 것입니다. 나는 일상적인 bash/zsh 작업에 매우 만족하지만 충분히 원활하지 않습니다!

또한 정규식 일치가 없는 경우도 적절하게 처리해야 합니다.

답변1

를 사용하면 zsh대략적인 일치 기능에 따라 다양한 방법을 사용할 수 있습니다.

autoload zmv # best in ~/.zshrc
zmodload zsh/stat

dest=~/Categories
categories=(television lightbulb motorcar etc)
mkdir -p -- $dest/${(C)^categories}

zmv -n '(**/)(*[^0-9])<->(.*)' \
       '$dest/${c::=${${(CM)categories:#(#a3)$2}:-unknown}}/$c-$(
          zstat -F %FT%T%z +mtime -- $f)$3'

${(M)categories:#(#a3)$2}배열 조회( $2숫자 앞 부분)는 categories최대 3개까지 허용됩니다.실수(다른 문자, 전치, 삽입, 삭제).

정상이면 제거합니다 -n(모의 실행).

귀하의 방법은 다음과 같습니다.

autoload zmv # best in ~/.zshrc
zmodload zsh/stat

dest=~/Categories
typeset -A categories

categories=(
  levis Television
  ghtbu Lightbulb
  otorc Motocar
)

mkdir -p -- $dest/$^categories

for k (${(k)categories}) (
  zmv -n "(**/)*$k*(.*)" '$dest/$categories[$k]/$categories[$k]-$(
          zstat -F %FT%T%z +mtime -- $f)$2'
)

아니면 만약에흔한문자는 항상 3위 부터 7위 까지 입니다 .

autoload zmv # best in ~/.zshrc
zmodload zsh/stat

dest=~/Categories

categories=(Television Lightbulb Motocar)

mkdir -p -- $dest/$^categories

for c ($categories) (
  zmv -n "(**/)*$c[3,7]*(.*)" '$dest/$c/$c-$(
          zstat -F %FT%T%z +mtime -- $f)$2'
)

답변2

아마도 가장 효율적인 접근 방식은 아닐 것입니다. 그러나 저는 이 문제를 해결하여 파일 이름의 문자열을 디렉터리와 일치시키고 현재 열거형이 무작위이므로 고유한 값을 유지하기 위해 개수를 세어 보겠습니다.

homedir=~/Categories
eval homedir=$homedir

cats="Television Lightbulb Bananas Motorcar"
declare -A count

for cat in $cats; do if [ ! -d $homedir/$cat ]; then mkdir -p $homedir/$cat; fi; done

while read f; do
    r=${f##*/}
    r=${r%.*}
    r=$(grep -Po "[a-z]+" <<<$r)
    for cat in $cats; do
        if [ $(grep -i "$r" <<< $cat) ]; then
            ((count[$cat]++))
            mv "$f" $homedir/$cat/$cat-$(printf "%03g" ${count[$cat]}).${f##*.}
        fi
    done
done <<< $(find ./banana/ -type f) 

일치하지 않는 콘텐츠는 grep자동으로 루프를 종료하고 나중에 특별한 주의를 끌 수 있도록 제자리에 남겨집니다.

파일 이름 조합에 포함하려는 다른 내용을 입력할 수 있습니다. 마지막 수정 날짜는 다음과 같습니다.

$(stat -c %Y $f)

관련 정보