이름이 잘못된 파일이 여러 개 있습니다.
$ 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.R
i와 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
첫 번째 이름을 바꾸면 다음 이름과 충돌하므로 실패합니다. 이를 위해서는 파일 이름을 역순으로 제공하거나 먼저 충돌하지 않는 형식으로 변경한 다음 추가 문자를 추가하여 다시 되돌려야 합니다.
답변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>
'