
rename
명령(정규식 사용)을 사용하여 파일 세트의 이름을 바꿔야 합니다 . 몇 번 시도한 후에도 예상한 결과를 얻는 표현식을 찾을 수 없습니다.
다음과 같은 파일 패턴이 있습니다.
접두사_some_name_other.txt
모든 파일은 " prefix_
" 문자열로 시작하고 " _other.txt
"로 끝납니다.some_name부분은 밑줄로 구분된 여러(영숫자) 단어로 구성될 수 있습니다. 따라서 다음이 가능합니다.
prefix_one_name_other.txt
prefix_this_is_my_name_1_this1_other.txt
파일 이름을 다음과 같이 바꿔야 합니다.
other_one-name_날짜 시간 other_this-is-내 이름-1-this1_날짜 시간
다시 말해서:
- " "을(를) 삭제해야 합니다
prefix
(밑줄은 남겨두고). - "
other
" 토큰은 파일 이름의 시작 부분으로 이동합니다. - ~ 안에some_name, 밑줄(_)을 대시(-)로 변환
- 파일 이름 끝에 밑줄(뒤에some_name)은 남아 있어야 합니다
- 확장자 를 삭제하고
.txt
다음으로 대체해야 합니다.날짜 시간.
내가 시도한 것:
rename 's/fw_([a-z]+)_(\d)_(\w+\d)_(\w+)\.txt/$4_$1-$2-$3_'$datahora'/' *.txt
$datahora
가지다날짜 시간값(테스트됨). 이것은 예상대로 작동합니다
prefix_name_1_gnt1_other.txt
하지만 함께는 아니야
prefix_other_name_2_gnt2_other.txt
내가 어디서 잘못됐나요? 내가 또 어떻게 그 일을 성취할 수 있겠는가?
지금은 내가 가지고 있는 모든 파일 이름에 대해 작동하는 정규식을 찾을 수 없기 때문에 마음을 놓았습니다. 문자열의 첫 번째 요소는 항상 부분 prefix
이고 마지막 요소는 other.txt
문자열의 일부라는 것을 알고 있습니다. 따라서 문자열을 배열로 분할하고 새 이름을 만드는 데 필요한 항목을 얻을 수 있습니다. 사실 그런 것입니다.
datahora="20140718-080000"
arrfiles=( *.txt )
for curfile in ${arrfiles[*]}
do
arrparts=( ${curfile//_/ } )
numitems=${#arrparts[*]}
newname=""
for (( c=1; c<numitems-1; c++ ))
do
newname+="${arrparts[c]}-"
done
newname=${newname%-}
arrparts[numitems-1]=${arrparts[numitems-1]/.txt/}
newname="${arrparts[numitems-1]}_${newname}_$datahora"
echo "$curfile pasa a $newname"
mv ${curfile} ${newname}
done
이런 식으로 수행한 후 @peterph 제안을 다시 시도하고 마지막으로 일부 이름 바꾸기 정규식 조합을 완료했습니다. 다음과 같이 생각합니다.
rename 's/_/-/g' *.txt
rename 's/^fw-(.*)-([^-]*)(\.txt)/$2.$1$3/' *.txt
rename 's/(\w+)\.(.*)(\.txt)/$1_$2_'$datahora'/' *.txt
최선의 접근 방식이 무엇인지 잘 모르겠습니다. 제 생각에는 regex 변형이 더 우아해 보이지만 작업을 수행하려면 세 번의 이름 바꾸기 작업(디스크에 세 번 액세스)이 필요한 반면 변형은 array
디스크에 한 번만 씁니다.
¿이 두 가지 솔루션에 대해 어떻게 생각하십니까?...
다시 한 번 감사드립니다.
답변1
rename
여러 대체 명령을 받아들일 수 없다면그리고파일 이름의 루트( some_name
)에는 밑줄이 두 개 이상 포함될 수 있습니다. 이 작업은 두 단계로 수행해야 합니다. a) 밑줄을 대시로 바꾸고 b) 파일 이름에서 (다시) 청크를 이동합니다.
찾고 있는 정규식은 다음과 같습니다.
rename 's/_/-/g' *.txt
rename 's/^prefix-(.*)-([^-]*).txt$/$2_$1_'$DATETIME'/' *txt
첫 번째는 밑줄을 사용하여 대시 번역을 수행하고 후자는 루트와 접미사를 교환하고 DATETIME
환경 변수의 내용을 이름에 추가합니다. 물론 접두사와 확장자는 생략합니다.
해당 [^-]*
부분은 대시를 포함하지 않는 모든 문자열과 일치합니다. 접미사가 항상 동일한 경우 접두사의 경우와 같이 그대로 입력할 수 있습니다(반대의 경우도 마찬가지입니다. 접두사가 다를 수 있는 경우 ^[^-]*-
파일 시작 부분 사이에 대시가 포함되지 않은 문자열과 일치하도록 사용). 이름과 (따라서) 첫 번째 대시).
rename
여러 명령을 지원하는 경우 해당 명령을 연결하면 됩니다.
rename 's/_/-/g;s/^prefix-(.*)-([^-]*).txt$/$2_$1_'$DATETIME'/' *txt