파일 이름의 한 자리 숫자에 0을 추가합니다.

파일 이름의 한 자리 숫자에 0을 추가합니다.

이것은 내 샘플 파일입니다.

user@linux:~$ ls -l | cut -d ' ' -f 10-

ch 10 - file.txt
ch 2 - file.txt
ch 3 - file.txt
ch 4a - file.txt
ch 5 - file.txt
user@linux:~$ 

0임의의 단일 숫자(포함 )를 추가하고 싶으 4a므로 최종 출력은 다음과 같습니다.

user@linux:~$ ls -l | cut -d ' ' -f 10-

ch 10 - file.txt
ch 02 - file.txt
ch 03 - file.txt
ch 04a - file.txt
ch 05 - file.txt
user@linux:~$ 

Linux에 내장된 도구를 사용하여 이것이 가능합니까?

답변1

무늬

'ch '[1-9][!0-9]*'- file.txt'

변경해야 하는 모든 파일 이름(표시하는 파일 이름 외부)과 일치합니다. 즉, 로 시작하고 ch 그 뒤에 1에서 9 사이의 숫자가 오고 그 뒤에 숫자가 아닌 이름이 오는 모든 파일 이름과 일치합니다. 그 이후에는 모든 문자를 허용하며 이름은 로 끝나야 합니다 - file.txt.

우리는 이 파일들을 반복할 수 있습니다

for name in 'ch '[1-9][!0-9]*'- file.txt'; do
    ...
done

이제 목표는 0해당 비트 뒤에 하나를 삽입하는 것 입니다 ch . ch 하위 문자열을 제거하고 다음으로 바꾸면 됩니다 ch 0.

for name in 'ch '[1-9][!0-9]*'- file.txt'; do
    newname='ch 0'${name#ch }
done

매개변수 대체는 포함된 경우 ${name#ch }로 확장됩니다 (접두사 제거됨 ).2 - file.txt$namech 2 - file.txtch 

그런 다음 파일 이름을 바꿀 수 있습니다.

for name in 'ch '[1-9][!0-9]*'- file.txt'; do
    newname='ch 0'${name#ch }

    printf 'would rename "%s" into "%s"\n' "$name" "$newname"
    # mv -i "$name" "$newname"
done

루프를 한 번 실행한 후 #주석 처리된 mv명령이 포함된 줄을 제거하고 올바른 작업을 수행하는지 확인하세요.

표시되는 파일 이름이 주어지면 위의 루프가 출력됩니다.

would rename "ch 2 - file.txt" into "ch 02 - file.txt"
would rename "ch 3 - file.txt" into "ch 03 - file.txt"
would rename "ch 4a - file.txt" into "ch 04a - file.txt"
would rename "ch 5 - file.txt" into "ch 05 - file.txt"

답변2

Lary Wall의 rename/ prename( renameDebian/Ubuntu, prenameRedHat/Fedora) 사용:

rename -n 's/^ch (\d) /ch 0$1 /' *

-n연습 실행의 경우 실제 실행을 위해 제거(또는 "-v"로 대체)합니다.

답변3

그리고 zsh:

autoload zmv # best in .zshrc
zmv -n '*[0-9]*' '${f//(#m)<->/${(l:2::0:)MATCH}}'

( -n만족하면 삭제(테스트 실행)).

ef l- 모든 숫자를 너비 2로 채웁니다.

그것도 조심해자르기너비가 2인 숫자( 1234-2.txt) 34-02.txt.

당신이 무슨 뜻인지 확실하지내장, 특히 관련하여리눅스이것은 단지 커널일 뿐입니다. autoloadzsh 내장형이지만 zmv자동 로드 가능 함수는 mv기본적으로 내장되어 있지 않은 유틸리티를 호출합니다(그러나 내장형으로 만들 수 있음 zmodload zsh/files).

답변4

이것이 당신이 찾고 있는 것입니다.

수행해야 할 작업은 기본적으로 다음과 같습니다.

1. 숫자가 한자리인지, 두자리인지 확인하세요. 한 자리 숫자이고 값이 9보다 작거나 같으면 파일 이름을 바꾸십시오. 이는 다음과 같이 간단해야 합니다.

(( someDigit <= 9 )) && [[ ${#someDigit'slength} -lt 2 ]]

2. 문자가 포함된 파일이 있으므로 다음과 같이 저장할 수 있습니다.

digit=$( echo $file | cut -d '-' -f1 | grep ch | awk '{print $2}' );

3. 그런 다음 첫 번째 옵션과 비교할 수 있도록 숫자를 필터링합니다. tr -d다음과 같이 옵션에서 필요하다고 생각되는 필터를 더 추가하세요 .

digitOnly=$( echo $digit | tr -d [a-Z] );  

4. 그런 다음 파일 이름을 바꿀 디렉터리에서 루프를 실행합니다. 이 모든 것을 구현하면 다음과 같습니다.

for file in *file.txt; do
  digit=$( echo $file | cut -d '-' -f1 | grep ch | awk '{print $2}' );
  digitOnly=$( echo $digit | tr -d [a-Z] );
  if (( digitOnly <= 9 )) && [[ ${#digitOnly} -lt 2 ]]; then
    # mv "${file}" "ch 0${digit} - file.txt"
    echo "'${file}' is renamed to 'ch 0${digit} - file.txt'";
  fi
done

mv에서 #을 제거한 후 만족스러우면 실행하십시오. 당신의 예를 들어보세요:

touch 'ch 10 - file.txt' 'ch 2 - file.txt' 'ch 3 - file.txt' 'ch 4a - file.txt' 'ch 5 - file.txt'

그런 다음 스크립트를 실행하거나 위의 내용을 복사하여 붙여 넣으면 다음과 같은 출력이 제공 script됩니다 .bash

'ch 2 - file.txt' is renamed to 'ch 02 - file.txt'
'ch 3 - file.txt' is renamed to 'ch 03 - file.txt'
'ch 4a - file.txt' is renamed to 'ch 04a - file.txt'
'ch 5 - file.txt' is renamed to 'ch 05 - file.txt'

분명히 함수로 래핑한 다음 파일 패턴 검색과 같은 입력을 허용하여 더 일반적으로 만들 수도 있지만 귀하의 질문에는 그럴 필요가 없습니다. 따라서 현재 답변이 질문에 명시된 상황을 잘 처리한다고 생각합니다.

관련 정보