번호 다시 매기기 및 이름 바꾸기

번호 다시 매기기 및 이름 바꾸기

다음과 같은 형식으로 많은 수의 파일 이름을 바꿔야 하는 상황이 발생했습니다.

file.csv
file_1.csv
file_2.csv
file_3.csv
file_4.csv
file_5.csv
file_6.csv
file_7.csv
file_8.csv

더 나은 정렬을 위해서는 다음이 필요합니다.

file_1.csv
file_2.csv
file_3.csv
file_4.csv
file_5.csv
file_6.csv
file_7.csv
file_8.csv
file_9.csv

즉, 첫 번째 파일의 이름을 수동으로 바꿀 수 있지만 나머지 " _#" 파일 에 대해서는 +1.

rename -n -v 's/_(.*)./.(\1+1)./' 

하지만 얻었어

file_(1+1).csv
file_(2+1).csv

등.

_#" " 파일을 일괄적으로 유지하는 간단한 방법이 있습니까 ?

추신, 아직은 더 좋습니다

file_01.csv
. . .
file_09.csv
file_10.csv
. . .

가능하다면.

고쳐 쓰다:

답변해 주셔서 감사합니다. 0으로 채워진 이름으로 이름을 바꾸었기 때문에 파일 이름이 충돌하지 않으므로 명령이 다음과 같이 단순화되었습니다.

touch file.csv file_{1..9}.csv

$ rename -v 's/^(file_)(\d+)(\.csv)$/$1 . (sprintf "%02i", $2 + 1) . $3/e' file_*
file_1.csv renamed as file_02.csv
file_2.csv renamed as file_03.csv
file_3.csv renamed as file_04.csv
file_4.csv renamed as file_05.csv
file_5.csv renamed as file_06.csv
file_6.csv renamed as file_07.csv
file_7.csv renamed as file_08.csv
file_8.csv renamed as file_09.csv
file_9.csv renamed as file_10.csv

마지막 두 파일 이름을 참고하세요.

file_09.csv
file_10.csv

답변1

Perl의 정규 표현식 수정자를 사용하여 /e연산의 오른쪽을 s///Perl 표현식으로 평가하도록 해야 합니다.

파일 이름도 정렬해야 합니다.취소가장 높은 번호의 파일 이름이 바뀌도록 번호 순서앞으로낮은 번호의 파일 이름(그렇지 않으면 파일 이름 충돌이 발생합니다. 기본적 -f으로 rename. 이를 위해 NUL 종료 입력에 대해 GNU findwith -print0및 GNU sortwith를 사용 하고 역방향 버전(즉, "자연") 정렬을 사용하겠습니다. 옵션 은 두 번째 필드에서 정렬하는 데에도 사용됩니다.-z-r-V-t _-k 2

이름 바꾸기 옵션을 -d사용하면 경로 이름의 파일 이름 부분만 이름이 바뀌고 -0표준 입력에서 NUL로 구분된 파일 목록을 사용하게 됩니다.

예를 들어

$ touch file.csv file_{1..8}.csv
$ find . -name 'file_*.csv' -print0 |
    sort -z -t _ -k2 -r -V |
    rename -d -0 's/^(file_)(\d+)(\.csv)$/$1 . ($2 + 1) . $3/e'
$ mv file.csv file_1.csv
$ ls -l
total 5
-rw-r--r-- 1 cas cas 0 Aug 21 15:22 file_1.csv
-rw-r--r-- 1 cas cas 0 Aug 21 15:22 file_2.csv
-rw-r--r-- 1 cas cas 0 Aug 21 15:22 file_3.csv
-rw-r--r-- 1 cas cas 0 Aug 21 15:22 file_4.csv
-rw-r--r-- 1 cas cas 0 Aug 21 15:22 file_5.csv
-rw-r--r-- 1 cas cas 0 Aug 21 15:22 file_6.csv
-rw-r--r-- 1 cas cas 0 Aug 21 15:22 file_7.csv
-rw-r--r-- 1 cas cas 0 Aug 21 15:22 file_8.csv
-rw-r--r-- 1 cas cas 0 Aug 21 15:22 file_9.csv

이것은 약간 단순화될 수 있지만 파일 이름을 바꾸면 안 되는 가능성을 피하기 위해 정규식 file_에서 , 하나 이상의 숫자 및 확장자를 명시적으로 찾고 캡처하도록 만들었습니다 ..csv

파일 번호를 0으로 채우려면 이 sprintf기능을 사용하십시오. 예를 들어

... | rename -0 -d -v 's/^(file_)(\d+)(\.csv)$/$1 . (sprintf "%02i", $2 + 1) . $3/e'
Reading filenames from file handle (GLOB(0x555555905960))
./file_8.csv renamed as ./file_09.csv
./file_7.csv renamed as ./file_08.csv
./file_6.csv renamed as ./file_07.csv
./file_5.csv renamed as ./file_06.csv
./file_4.csv renamed as ./file_05.csv
./file_3.csv renamed as ./file_04.csv
./file_2.csv renamed as ./file_03.csv
./file_1.csv renamed as ./file_02.csv

답변2

그리고 zsh:

$ autoload -Uz zmv # best in ~/.zshrc
$ LC_ALL=C zmv -f -n '(file)(|_(<->))(.csv)(#qnOn)' '${1}_$(($3+1))$4'
mv -- file_11.csv file_12.csv
mv -- file_10.csv file_11.csv
mv -- file_9.csv file_10.csv
mv -- file_8.csv file_9.csv
mv -- file_7.csv file_8.csv
mv -- file_6.csv file_7.csv
mv -- file_5.csv file_6.csv
mv -- file_4.csv file_5.csv
mv -- file_3.csv file_4.csv
mv -- file_2.csv file_3.csv
mv -- file_1.csv file_2.csv
mv -- file.csv file_1.csv

또는 0-padding을 사용하여 ${(l[2][0])...}왼쪽 패딩 매개변수를 사용하여 플래그를 확장합니다.

$ LC_ALL=C zmv -fn '(file)(|_(<->))(.csv)(#qnOn)' '${1}_${(l[2][0])$(($3+1))}$4'
mv -- file_11.csv file_12.csv
mv -- file_10.csv file_11.csv
mv -- file_9.csv file_10.csv
mv -- file_8.csv file_09.csv
mv -- file_7.csv file_08.csv
mv -- file_6.csv file_07.csv
mv -- file_5.csv file_06.csv
mv -- file_4.csv file_05.csv
mv -- file_3.csv file_04.csv
mv -- file_2.csv file_03.csv
mv -- file_1.csv file_02.csv
mv -- file.csv file_01.csv

( 가능한 경우 삭제 -n(시운전) ).

그러면 이 glob에서 생성된 파일의 이름이 변경됩니다. extendedglob여기서:

  • <->일련의 숫자와 일치합니다( <x-y>지정된 범위 없이 연산자와 일치하는 십진 정수입니다).
  • (#q...)다음과 같이 glob 한정자를 지정합니다.
    • n: 숫자 전역 정렬 전환
    • On: 이름을 기준으로 역순으로 정렬합니다. 그래서 file8before file7, 위의 Numericglobsort 덕분에 file10before file9. 이는 LC_ALL=C정렬 알고리즘에서 합계가 무시되지 않도록 하기 위한 것입니다 _..file.csvfile_1.csv

대체에서 $1, ...에는 in 연산자와 유사한 패턴 으로 $2각 쌍에 대한 일치 항목이 포함됩니다 .()perls///

-f는 온전성 검사를 비활성화하는 데 사용됩니다 . 즉 , 이미 존재하는 항목으로 이름이 변경된 것에 zmv대해 불평합니다 (그때까지 이미 이름이 변경된 경우에도 ).file6.csvfile7.csvfile7.csvfile8.csv

renamePerl을 사용 하여 이름을 바꿀 수 있지만 zsh올바른 순서로 목록을 전달하려면 glob과 같은 것이 여전히 필요합니다.

$ (LC_ALL=C; rename -f -n '
    s{^(file)(?:_(\d*))?(\.csv)\Z}{
      "${1}_" . (($2 // 0) + 1) . $3}se
   ' file(|_<->).csv(nOn))
rename(file_11.csv, file_12.csv)
rename(file_10.csv, file_11.csv)
rename(file_9.csv, file_10.csv)
rename(file_7.csv, file_8.csv)
rename(file_6.csv, file_7.csv)
rename(file_5.csv, file_6.csv)
rename(file_4.csv, file_5.csv)
rename(file_3.csv, file_4.csv)
rename(file_2.csv, file_3.csv)
rename(file_1.csv, file_2.csv)
rename(file.csv, file_1.csv)

(($2 // 0) + 1)예를 들어 패딩을 0 으로 바꿉니다 sprintf("%02d", ($2 // 0) + 1).

해당 파일이 없어 설치할 수 없지만 zshGNU 시스템을 사용하는 경우 bash다음 명령을 사용하여 올바른 순서로 파일을 가져올 수 있습니다.

eval "files=(
  $(
    shopt -s extglob failglob
    export LC_ALL=C
    ls --quoting-style=shell-always -rvd file?(_+([0-9])).csv
   )
)"

ls -rv파일을 역버전 순서로 나열하려면 GNU를 사용하십시오 .

rename ... "${files[@]}"그런 다음 위와 rename동일한 코드를 사용하여 이름 바꾸기를 호출합니다.

여기서는 파일 이름이 매우 간단하고 일치하는 다른 파일이 없다고 가정하고 file*.csv기본값을 사용하여 $IFS이 작업을 수행할 수도 있습니다(여전히 GNU ls를 사용하지만 Bourne과 유사한 쉘을 사용함).

rename ... $(LC_ALL=C ls -rvd file*.csv)

답변3

한 가지 접근 방식은 다음과 같습니다.

set -- file_*.csv

while [ "$#" -gt 0 ]; do
  set -- "$#" "$@"
  mv -- "file_$1.csv" "file_$#.csv"
  shift 2
done

mv file.csv file_1.csv

0으로 채워진 파일 이름을 유지하려면 mv명령문을 다음과 같이 변경하십시오.

mv -- "file_$1.csv" "$(printf 'file_%02d.csv\n' "$#")"
mv file.csv file_01.csv

명령줄 인수가 엉망이 되는 것이 걱정된다면 함수 내에서 이 모든 작업을 수행하고 해당 함수를 호출할 수 있습니다.

관련 정보