이것은 내 샘플 파일입니다.
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
$name
ch 2 - file.txt
ch
그런 다음 파일 이름을 바꿀 수 있습니다.
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
( rename
Debian/Ubuntu, prename
RedHat/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
.
당신이 무슨 뜻인지 확실하지내장, 특히 관련하여리눅스이것은 단지 커널일 뿐입니다. autoload
zsh 내장형이지만 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'
분명히 함수로 래핑한 다음 파일 패턴 검색과 같은 입력을 허용하여 더 일반적으로 만들 수도 있지만 귀하의 질문에는 그럴 필요가 없습니다. 따라서 현재 답변이 질문에 명시된 상황을 잘 처리한다고 생각합니다.