내 디렉토리에 다음과 같은 파일이 있습니다.
$ ls *
-008.png 0052.png -002.jpg 0043.png -005.png 0044.png ...
파일을 하위 디렉터리에 복사하고 subdir
(기존 파일을 덮어쓰지 않고) 파일 이름에 주어진 숫자(예: 10)를 추가하여 파일 이름을 바꾸고 싶습니다.
$ ls subdir/*
0002.png 0062.png 0008.jpg 0053.png 0005.png 0054.png ...
이것은 내 bash 명령입니다
for filename in *
do
basename=${filename%.*}
extname=${filename#*.}
basename_new=$(printf %04d $((10#${basename}+10))); # 10#-008: value too great for base (error token is "003")
if [ ! -e subdir/"$basename_new".* ]; # [: subdir/.: binary operator expected
cp "$filename" "$basename_new"."$extname"
fi
done
부정적인 이름을 가진 일부 파일의 경우 for와 같은 오류가 발생합니다 -008.png
(그러나 for는 아님 -002.png
, 이유는 잘 모르겠습니다).
다음에 할당된 행의 경우 basename_new
:
10#-008: value too great for base (error token is "008")
다음 줄의 경우 if
:
# [: subdir/.: binary operator expected
이 오류가 무엇을 의미하는지 알고 싶습니다. 어떻게 해결할 수 있나요?
감사해요.
답변1
대시로 시작하는 단어는 일반적으로 옵션으로 간주됩니다. 이렇게 하면 ls *
명령 이 이해하지 못하는 일련의 옵션을 ls
받아 ls 001.png -002.png ...
처리합니다 . , , ... -002.png
등의 많은 명령에서도 마찬가지입니다.cp
mv
해결 방법 1: 파일 앞에 경로를 붙입니다. 모든 경우에 유효합니다.
ls ./*
해결 방법 #2: 특히 GNU 세계의 많은 명령은 이중 대시를 인수로 허용하여 뒤에 오는 내용이 옵션이 아님을 나타냅니다.
ls -- *
그러나 선행 대시는 루프에 영향을 주지 않습니다 for
.
"값이 밑수에 비해 너무 크다"는 것은 -008
0부터 시작해서 8진수로 처리되기 때문입니다. 그러나 8은 유효한 8진수가 아닙니다. 빠른 수정은 다음을 사용하는 것입니다 bc
.
printf -v basename_new %04d "$(bc <<< "${basename} + 10")"
문제는 if
null로 인해 발생 basename_new
하며 위의 수정 사항으로 사라집니다.
답변2
그리고 zsh
:
$ autoload zmv
$ zmv -n '((-|)<->).(png|jpg)' '${(l:4::0:)$(($1 + 10))}.$3'
mv -- -002.jpg 0008.jpg
mv -- 0043.png 0053.png
mv -- 0044.png 0054.png
mv -- 0052.png 0062.png
mv -- -005.png 0005.png
mv -- -008.png 0002.png
( -n
실제 수행된 작업 제거)
(-|)
glob:-
또는 "": 선택 사항-
<->
glob: 일련의 십진수(유사<x-y>
하지만 경계가 없음).${(l:4::0:)param}
: 왼쪽 패딩(및 잘림)이 0인 길이 4입니다.$(($1 + 10))
(...)
: 패턴에서 캡처된 데이터의 첫 번째 쌍으로 10씩 증가합니다(zsh
0으로 시작하는 숫자가 8진수로 처리되는 데 문제가 없습니다. 이 옵션을 설정하더라도 정상적인 zsh 런타임으로 되돌리는 옵션에는octalzeroes
영향을 미치지 않습니다 .zmv
답변3
10#-008
-008
10진수로 변환 되지 않습니다 . 10#
기호보다는 숫자 앞에 와야 하기 때문인 것 같아요 .