내 문제는 간단한 것 같아요. 고정된 접두어와 이전 파일 이름의 일부인 숫자(2자리)를 포함하는 새 파일 이름을 만들고 싶습니다.
예: "blableblub23.pdf" 파일이 있고 이름을 "Newfile 23"으로 변경하여 이동하고 싶습니다. 여기서 "Newfile"은 고정 접두사입니다.
따라서 먼저 이전 파일 이름에서 숫자가 아닌 모든 항목을 제거해야 하는데 이것이 주요 문제입니다. 나는 노력하고있다
paperno=expr match "$filename" '.*([0-9][0-9]).*'
filename_new="Newfile $paperno"
나는 항상 숫자 없이 filename_new = "Newfile"을 얻지만 "Newfile 23"을 기대합니다.
내 잘못이 뭐예요?
정말 고마워요 ;)
명확히 하기 위해 편집됨:
파일 이름 어디에든 두 자리 숫자가 포함된 파일 이름($filename에 저장됨)이 있습니다.
Test_bla_blub_23_and_more.pdf Test_23.pdf Test_23_bla.pdf
새 파일 이름을 만들기 위해 다른 변수 $paperno에 숫자(예: 23)를 저장하고 싶습니다.
파일 이름에 숫자가 없거나 그 이상의 숫자가 있는 경우 $paperno 변수는 비어 있거나 0이어야 합니다. 숫자가 여러 개인 경우 모든 숫자를 반환하면 수락됩니다. 즉:
Test_12_bla_blub_23_and_more.pdf => $paperno = 1223
죄송합니다. 저는 쉘 스크립팅, zsh 및 정규 표현식을 처음 접했습니다.
답변1
zsh
정규식 일치(ERE 및 PCRE)에 대한 일부 기본 지원이 있으며 정규식 이상으로 확장된 glob 연산자도 있습니다. 오래되고 손상된 설계 명령을 사용할 필요가 없습니다 expr
(BRE 사용,기초적인정규식 자체).
일괄 이름 바꾸기 도구도 있습니다.
autoload -Uz zmv
zmv -v '(*[^0-9]|)(<->).pdf' 'Newfile $1'
(*)(<->).pdf
는 .*([0-9][0-9])\.pdf
작동하지 않습니다. foo1234.pdf
예를 들어 *
(resp. )는 (resp. ) .*
와 일치하여 가능한 가장 작은 ( ) 만 남기기 때문 입니다. (각각 ) .foo123
foo12
4
<->
34
[0-9][0-9]
PCRE를 사용하는 경우 다음과 같이 탐욕스럽지 않은 일치 연산자를 사용할 수 있습니다.
set -o rematchpcre
[[ $file =~ '^.*?(\d+)\.pdf\z' ]]
number=$match[1]
.*
그러나 정규식을 처음에 고정하지 않으면 필요하지 않습니다(위에서는 ^
암시 expr
적으로 처음에 고정됨).
[[ $file =~ '(\d+)\.pdf$' ]]
( PCRE 이후 $
ERE의 기본값 ).\z
set -o rematchpcre
또는 여기에서 다음을 수행할 수 있습니다.
zmv '*<->.pdf' 'Newfile ${(M)${f:r}%%<->}'
${f:r}
연장할 곳루트 이름(확장자 제거) ${(M)param%%pattern}
일치하는 인수의 가장 긴 꼬리까지 확장합니다 pattern
( <->
여기서는 제한 없이 모든 ASCII 십진수 시퀀스와 일치합니다 <x-y>
).
파일 이름에서 모든 숫자를 추출하려면(예 : 또는 다음 foo-123-bar.pdf
으로 이름 바꾸기 )Newfile 123
foo1bar2.pdf
Newfile 12
zmv -v '*[0-9]*.pdf' 'Newfile ${f//[^0-9]}'
을(를) 확장 ${f//pattern/replacement}
하고 $f
모든 항목을 pattern
바꿉니다 replacement
. 여기서는 치환을 생략하므로 십진수를 제외한 모든 문자를 아무것도 치환하지 않습니다.
.pdf
완전성을 위해 이전 에 숫자 목록을 추출하려면 expr
다음을 수행해야 합니다.
number=$(expr "x$file" : '.*[^0123456789]\([0123456789]\{1,\}\)\.pdf$')
해당 번호를 찾지 못하면 실패한 종료 상태를 반환하고, 해당 번호를 찾지 0
못하면 00
...000
이 접두사는 확장이 연산자 인 경우 연산자로 처리되는 설계 버그를 x
해결하기 위한 것입니다 .expr
$file
expr
이는 match
표준 expr
연산자가 아니며 표준 연산자는 이 :
연산자입니다.
다시 말하지만, 70년대에는 매우 손상되고 제한적인 유틸리티였으며 특히 매우 강력한 텍스트 추출 및 서식 지정 기능이 내장되어 있기 expr
때문에 오늘날에도 계속 사용할 이유가 없습니다 .zsh
답변2
표현식 출력문자 수가 일치합니까? paperno 변수를 인쇄해 보셨습니까? 나는 그것이 당신에게 예상되는 결과를 줄 것이라고 생각하지 않습니다
가능한 방법은 모든 문자열을 제거하고 "."으로 잘라내어 숫자를 얻는 것입니다. 좋다:
charstostrip=expr match "$filename" '^[a-zA-Z]+$'
modified=${$filename:$charstostrip}
fn_number=${echo $modified | cut -d . -f1}
filename_new="Newfile $fn_number"