파일 이름의 변수 부분(일부만)을 증가시키는 스크립트나 명령줄을 어떻게 만듭니까?

파일 이름의 변수 부분(일부만)을 증가시키는 스크립트나 명령줄을 어떻게 만듭니까?

이름이 잘못된 파일이 여러 개 있습니다.

$ ls
devoirNote1_1_2.R  devoirNote1_1_5.R  devoirNote1_4_1.R
devoirNote1_1_3.R  devoirNote1_1.R    devoirNote1.R
devoirNote1_1_4.R  devoirNote1_2_1.R  example140.R

devoirNote1_i_j.Ri와 j 정수를 devoirNote1_4_1.R제외한 모든 것을 변경 하고 싶습니다 devoirNote1_{i+1}_j.R(그냥 devoirNote1_4_1.R동일하게 유지하세요).

mv유사한 명령을 사용하려고 생각했지만 mv devoirNote1_*_2.R devoirNote1_2_2.R여러 파일이 일치할 때(예: if 및 devoirNote1_1_2.R둘 다 존재하는 경우) devoirNote1_3_2.R문제가 발생합니다 .

그렇다면 파일 이름의 변수 전체 대신에 하나의 변수를 증가시켜 파일 이름을 바꾸는 스크립트나 명령줄을 어떻게 만듭니까?

답변1

Perl의 rename유틸리티 (*) 를 이 목적으로 사용할 수 있습니다. 주어진 Perl 명령을 주어진 각 파일 이름에 적용하고 명령이 이름을 변경한 이름으로 파일 이름을 바꿉니다.

따라서 _1_glob _2_과 일치하는 모든 파일이 변경됩니다.

rename 's/_1_/_2_/' devoirNote1_*_2.R

/e교체 부분이 리터럴 텍스트가 아닌 Perl 조각이 되도록 교체 명령을 수정하여 숫자를 늘릴 수 있습니다 .

rename -v 's/_(\d+)_/"_" . ($1 + 1) . "_"/e' devoirNote1_*_2.R

밑줄 사이에 숫자가 포함된 파일 이름 부분을 선택하고, 숫자를 캡처하고 $1, 숫자를 증가된 숫자로 바꾸고 밑줄을 다시 추가합니다. -v자세한 모드의 경우. 예제의 파일 목록을 사용하면 devoirNote1_1_2.R renamed as devoirNote1_2_2.R예상대로 인쇄됩니다.

영향을 받는 파일은 명령줄 끝에 있는 glob과 일치하는 파일입니다.

1_1_2그러나 예를 들어 및 가 있는 경우 1_2_2첫 번째 이름을 바꾸면 다음 이름과 충돌하므로 실패합니다. 이를 위해서는 파일 이름을 역순으로 제공하거나 먼저 충돌하지 않는 형식으로 변경한 다음 추가 문자를 추가하여 다시 되돌려야 합니다.

(* util-linux 이름 바꾸기 도구가 아닙니다. 참조여기그리고여기)

답변2

두 개의(일괄) 이동에 대해 하나의 스크립트가 중복됩니다. 이 mmv유틸리티를 사용하십시오:

mmv devoirNote1_2_"*" devoirNote1_3_#1
mmv devoirNote1_1_"*" devoirNote1_2_#1

물론 그 순서대로요. 두 개 이상의 작업이 있으면 스크립트가 실제로 더 좋아질 것입니다.

답변3

여기서는 필터를 사용하여 negative lookaheads검색 목록에서 파일을 필터링합니다.*Note1_3_2.R*Note1_4_2.R

OP는 *Note1_4_2.R그것을 그대로 유지하기를 원합니다. => 이전 파일도 건드릴 수 없습니다. 즉, *Note1_3_2.R이것을 mv할 장소가 없기 때문입니다.

루프 for논리는 1과 2 사이의 인덱스 번호에 대해 수행하므로 reverse numeric sort비파괴적인 mv 작업을 수행할 수 있습니다.

perl -e '
   /(.*)_(\d+)_(.*)/ and
      rename $_, join "_", $1, $2+1, $3 or warn "Could not mv the file <<$_>>\n"
      for
         map  {                  $_->[0]                   }
         sort { $b->[2] <=> $a->[2] || $b->[1] <=> $a->[1] }
         map  {             [$_, /_(\d+)_(\d+)/]           }
         grep {     /^devoirNote1_(?![34]_1.R)\d+_\d+.R/   }
         <*.R>
'

관련 정보