점진적으로 정렬된 파일 범위의 이름 변경

점진적으로 정렬된 파일 범위의 이름 변경

"blah-10-blah", "blah-11-blah" 등...최대 "blah-30-blah"라는 이름의 파일 범위가 있다고 가정해 보겠습니다.

이름을 "blah-20-blah", "blah-21-blah" 등...최대 "blah-40-blah"로 변경하고 싶습니다.

터미널에서 이 작업을 수행할 수 있는 방법이 있나요?

답변1

넌 할 수있어:

#!/bin/bash
files=( blah-??-blah )
for ((i=${#files[@]}-1; i>=0; i--)); do

    first="${files[$i]%%-*}" 
    num="$(grep -o '[0-9]\+' <<<"${files[$i]}")" 
    last="${files##*-}"

        echo mv "$first-$num-$last" "$first-$((num+10))-$last" 
done

모든 것이 만족스러우면 | bash마지막에 추가하여 mv작업이 수행되도록 하세요.

  • 관련 파일 이름을 배열에 넣었습니다.files

  • 그런 다음 배열의 요소를 끝부터 즉 마지막부터 처음까지 반복했습니다.

  • first파일 이름의 첫 번째 부분, 즉 첫 번째 부분 이전의 부분을 갖습니다.-

  • last파일 이름의 마지막 부분, 즉 마지막 부분 이후의 부분을 갖습니다.-

  • num두 개 사이의 숫자를 갖게 됩니다.-

  • mv "$first-$num-$last" "$first-$((num+10))-$last"그에 따라 이름 바꾸기 작업을 수행합니다.

예:

$ ls -1
blah-10-blah
blah-11-blah
blah-12-blah
blah-13-blah
blah-14-blah
blah-15-blah
blah-16-blah
blah-17-blah
blah-18-blah
blah-19-blah
blah-20-blah
blah-21-blah
blah-22-blah
blah-23-blah
blah-24-blah
blah-25-blah
blah-26-blah
blah-27-blah
blah-28-blah
blah-29-blah
blah-30-blah
blah-foo-1
blah-foo-2

$ for ((i=${#files[@]}-1; i>=0; i--)); do first="${files[$i]%%-*}" \
    num="$(grep -o '[0-9]\+' <<<"${files[$i]}")" last="${files##*-}"; \ 
      echo mv "$first-$num-$last" "$first-$((num+10))-$last"; done

mv blah-30-blah blah-40-blah
mv blah-29-blah blah-39-blah
mv blah-28-blah blah-38-blah
mv blah-27-blah blah-37-blah
mv blah-26-blah blah-36-blah
mv blah-25-blah blah-35-blah
mv blah-24-blah blah-34-blah
mv blah-23-blah blah-33-blah
mv blah-22-blah blah-32-blah
mv blah-21-blah blah-31-blah
mv blah-20-blah blah-30-blah
mv blah-19-blah blah-29-blah
mv blah-18-blah blah-28-blah
mv blah-17-blah blah-27-blah
mv blah-16-blah blah-26-blah
mv blah-15-blah blah-25-blah
mv blah-14-blah blah-24-blah
mv blah-13-blah blah-23-blah
mv blah-12-blah blah-22-blah
mv blah-11-blah blah-21-blah
mv blah-10-blah blah-20-blah

$ for ((i=${#files[@]}-1; i>=0; i--)); do first="${files[$i]%%-*}" \
    num="$(grep -o '[0-9]\+' <<<"${files[$i]}")" last="${files##*-}";\ 
      echo mv "$first-$num-$last" "$first-$((num+10))-$last"; done | bash

$ ls -1
blah-20-blah
blah-21-blah
blah-22-blah
blah-23-blah
blah-24-blah
blah-25-blah
blah-26-blah
blah-27-blah
blah-28-blah
blah-29-blah
blah-30-blah
blah-31-blah
blah-32-blah
blah-33-blah
blah-34-blah
blah-35-blah
blah-36-blah
blah-37-blah
blah-38-blah
blah-39-blah
blah-40-blah
blah-foo-1
blah-foo-2

답변2

파일을 역순으로 처리하는 것이 중요합니다. 그렇지 않으면 대상 파일 이름을 가진 기존 파일로 인해 작업이 실패합니다.

find . -maxdepth 1 -type f -name 'blah-??-blah' -print0 | sort -zr | xargs -0 rename 's/-\K([0-9]{2})/$1+10/e'
  • find . -maxdepth 1 -type f -name 'blah-??-blah' -print0: 현재 작업 디렉터리에서 globbing 패턴과 일치하는 파일의 NULL로 구분된 목록을 인쇄합니다 blah-??-blah.
  • sort -zr: 목록을 역순으로 정렬합니다.
  • xargs -0 rename 's/-\K([0-9]{2})/$1+10/e': 대시 뒤의 처음 두 자리 숫자를 10씩 증가한 해당 값으로 대체하여 파일 이름을 바꿉니다.
% tree
.
├── blah-10-blah
├── blah-11-blah
├── blah-12-blah
├── blah-13-blah
├── blah-14-blah
├── blah-15-blah
├── blah-16-blah
├── blah-17-blah
├── blah-18-blah
├── blah-19-blah
├── blah-20-blah
├── blah-21-blah
├── blah-22-blah
├── blah-23-blah
├── blah-24-blah
├── blah-25-blah
├── blah-26-blah
├── blah-27-blah
├── blah-28-blah
├── blah-29-blah
└── blah-30-blah

0 directories, 21 files
% find . -maxdepth 1 -type f -name 'blah-??-blah' -print0 | sort -zr | xargs -0 rename 's/-\K([0-9]{2})/$1+10/e'
% tree
.
├── blah-20-blah
├── blah-21-blah
├── blah-22-blah
├── blah-23-blah
├── blah-24-blah
├── blah-25-blah
├── blah-26-blah
├── blah-27-blah
├── blah-28-blah
├── blah-29-blah
├── blah-30-blah
├── blah-31-blah
├── blah-32-blah
├── blah-33-blah
├── blah-34-blah
├── blah-35-blah
├── blah-36-blah
├── blah-37-blah
├── blah-38-blah
├── blah-39-blah
└── blah-40-blah

0 directories, 21 files

Zsh를 사용하는 경우 Zsh를 사용하면 파일 이름을 역순으로 확장할 수 있으므로 작업이 크게 단순화될 수 있습니다.

rename 's/-\K([0-9]{2})/$1+10/e' blah-??-blah(On)
% tree
.
├── blah-10-blah
├── blah-11-blah
├── blah-12-blah
├── blah-13-blah
├── blah-14-blah
├── blah-15-blah
├── blah-16-blah
├── blah-17-blah
├── blah-18-blah
├── blah-19-blah
├── blah-20-blah
├── blah-21-blah
├── blah-22-blah
├── blah-23-blah
├── blah-24-blah
├── blah-25-blah
├── blah-26-blah
├── blah-27-blah
├── blah-28-blah
├── blah-29-blah
└── blah-30-blah

0 directories, 21 files
% rename 's/-\K([0-9]{2})/$1+10/e' blah-??-blah(On)
% tree                                
.
├── blah-20-blah
├── blah-21-blah
├── blah-22-blah
├── blah-23-blah
├── blah-24-blah
├── blah-25-blah
├── blah-26-blah
├── blah-27-blah
├── blah-28-blah
├── blah-29-blah
├── blah-30-blah
├── blah-31-blah
├── blah-32-blah
├── blah-33-blah
├── blah-34-blah
├── blah-35-blah
├── blah-36-blah
├── blah-37-blah
├── blah-38-blah
├── blah-39-blah
└── blah-40-blah

0 directories, 21 files

답변3

이 접근 방식의 기본 아이디어는 모든 파일을 임시 "바구니" 디렉터리에 넣은 다음 하나씩 선택하여 새 이름을 만들고 새 이름을 사용하여 원래 디렉터리로 다시 이동하는 것입니다.

다음 스크립트는 이름을 바꾸려는 파일이 있는 디렉터리인 단일 인수( $1 )를 사용합니다.

데모

xieerqi:$ ls testdir                                                                                         
blah-10-blah  blah-20-blah  blah-30-blah  blah-40-blah

xieerqi:$ cat testdir/*                                                                                      
I am file 10 
I am file 20 
I am file 30 
I am file 40 

xieerqi:$ ./incrementNames.sh testdir                                                                        
blah-10-blah ../blah-20-blah
blah-20-blah ../blah-30-blah
blah-30-blah ../blah-40-blah
blah-40-blah ../blah-50-blah

xieerqi:$ ls testdir
blah-20-blah  blah-30-blah  blah-40-blah  blah-50-blah  TMP/

xieerqi:$ cat testdir/blah                                                                                   
blah-20-blah blah-30-blah blah-40-blah blah-50-blah 
xieerqi:$ cat testdir/blah-20-blah                                                                           
I am file 10 

xieerqi:$ cat testdir/blah-30-blah                                                                           
I am file 20 

스크립트

#!/bin/bash

if [ "$#" -ne 1 ]; then
    echo "Usage: incrementNames.sh /path/to/dir" && exit
fi

# navigate to target directory
# create temporary directory
cd "$1"
mkdir TMP
# move everything to TMP directory
find . -maxdepth 1 -type f -iname "*-*" -exec mv -t TMP {} \+
# drop down to TMP directory pick filesback into the directory , and rename them as we go
cd TMP
find .  -maxdepth 1 -type f -iname "*-*" -printf "%f\n"  | sort  | while IFS= read FILENAME
do
        NEW="$( awk -F '-'  '{print $1FS$2+10FS$3 }' <<< "$FILENAME")"
        echo "$FILENAME" "../$NEW" 
        mv "$FILENAME" ../"$NEW"
done

한정

text-number-text이 스크립트는 특히 패턴을 따르 거나 적어도 패턴을 따르는 파일을 위한 것입니다 text-number. 다른 사람들에게는 효과가 없을 것입니다

관련 정보