파일 이름 수정

파일 이름 수정

1000개의 파일이 있다고 가정해 보겠습니다 file1.txt.file1000.txt

숫자가 10으로 나누어지면 파일 이름을 변경해야 합니다.

이렇게 했는데 첫 글자만 바뀌었어요

for f in *.txt; do mv -- "$f" "${f%.txt}.doc"; done

답변1

@Henrik supports the community님의 의견이 매우 적절합니다. 또, 나는 항상인쇄명령을 실행한 다음 해당 명령을 다시 확인하세요. 이는 내장된 "테스트 실행" 기능을 제공합니다. 만약에명령이 올바르게 표시된 후 스크립트를 다시 실행하고 출력을 shOTOH로 파이프하면 명령이 올바르지 않아도 손상되지 않습니다.

for f in *0.txt
do
    printf 'mv -- %q %q\n' "$f" "${f%.txt}.doc"
done

printf의 지시문 을 보다 안전하게 사용할 것을 제안한 Stéphane Chazelas에게 감사드립니다 %q.

답변2

Perl 유틸리티( 실행 중인 UNIX 또는 Linux 배포판의 유형에 따라 이름이 지정될 수 있음)를 사용 rename하십시오 .prenameperl-renamefile-rename

예를 들어:

$ touch file{1..100}.txt
$ rename -n 'm/\w+(\d+)\.txt$/; if ($1 % 10 == 0) { s/\.txt$/.doc/ }' file*
rename(file100.txt, file100.doc)
rename(file10.txt, file10.doc)
rename(file20.txt, file20.doc)
rename(file30.txt, file30.doc)
rename(file40.txt, file40.doc)
rename(file50.txt, file50.doc)
rename(file60.txt, file60.doc)
rename(file70.txt, file70.doc)
rename(file80.txt, file80.doc)
rename(file90.txt, file90.doc)

이 스크립트는 정규식 일치를 수행하여 rename캡처 그룹 1( ) 이전의 숫자를 캡처합니다. 그런 다음 $1을 10으로 나눌 수 있으면 수정합니다..txt$1$_

참고: -n이 옵션을 사용하면 rename실제로 이름을 바꾸지 않고 이름을 바꿀 내용만 인쇄하는 시험 실행이 됩니다. 실제로 파일 이름을 바꾸려면 -n명령에서 해당 파일을 제거하거나 바꿔 -v자세한 출력을 얻으세요.

그건 그렇고, Perl은 rename그보다 훨씬 더 많은 일을 할 수 있습니다. 유효한 Perl 코드를 사용하여 파일 이름을 바꿀 수 있습니다. 코드가 변경되면 $_(현재 파일 이름) 이름도 변경됩니다. 변경되지 않으면 $_이름이 변경되지 않습니다. 실제로는 파일 이름 바꾸기 작업을 위한 특수 스크립트 언어입니다. 그런데 rename이 옵션을 사용하여 강제로 지정하지 않는 한 기존 파일의 파일 이름은 변경되지 않습니다 -f.

예를 들어, 숫자가 0 패딩으로 4자리가 되도록 모든 파일의 이름을 바꾸려면 s/\d+/sprintf("%04i",$&)/e이름 바꾸기 스크립트에 다음을 추가하세요.

$ rename -v 'm/\w+(\d+)\.txt$/;
             if ($1 % 10 == 0) { s/\.txt$/.doc/ };
             s/\d+/sprintf("%04i",$&)/e' file*
file100.txt renamed as file0100.doc
file10.txt renamed as file0010.doc
file11.txt renamed as file0011.txt
file12.txt renamed as file0012.txt
...
...
...
file98.txt renamed as file0098.txt
file99.txt renamed as file0099.txt
file9.txt renamed as file0009.txt

모든 파일 이름은 제로 패딩 버전으로 이름이 바뀌었고, 그 중 일부(10으로 나눌 수 있는 숫자의 파일 이름)도 doc로 이름이 바뀌었습니다.

답변3

다음은 작동하고 실행 시간을 절약할 수 있는 접근 방식입니다.

for f in *.txt
  do 
    fname="${f%.*}"  # strip away the extension
    n="${fname//[^[:digit:]]/}" # keep only the digits
    if (( n % 10 == 0)); then  # use modulo to check if the remainder is 0 when n is devided
      echo mv -- "$f" "foo_${fname}".doc 
    fi
  done

위의 논리를 이해하기 위해 숫자 1..1000의 예를 시도해 보겠습니다.

n=({1..1000}); for n in "${n[@]}"; do if (( n % 10 == 0 )); then echo "$n <-- can be divided by 10"; fi; done

그러면 다음이 생성됩니다.

10 <-- can be divided by 10
20 <-- can be divided by 10
30 <-- can be divided by 10
....
....

관련 정보