저는 CCTV 카메라 영상을 저장하기 위해 Synology를 사용합니다. CCTV 시스템의 파일을 Synology로 복사한 후 AVI 형식으로 변환했습니다. 따라서 내 파일 이름은 다음과 같습니다.
10.01.07-10.01.48[M][@0][0].dav.avi
다음과 같이 위의 이름에서 재귀적으로 이름을 바꾸고 싶습니다.
10.01.07-10.01.48.avi
각 파일 이름에는 항상 동일한 부분이 포함됩니다.[M][@0][0].dav.avi
rename
그런데 문제는 Synology 셸에 명령이 없다는 것입니다( sh
아니요 bash
).
find
나는 성공하지 못한 채 다양한 구문으로 명령을 사용해 보았습니다 . 해결책을 찾도록 도와주실 수 있나요?
답변1
다음을 수행할 수 있습니다.
find . -name '*\[M]\[@0]\[0].dav.avi' -type f -exec sh -c '
for file do
echo mv "$file" "${file%"[M][@0][0].dav.avi"}.avi"
done' sh {} +
( echo
괜찮아 보이면 삭제하세요.)
.dav.avi
또는 모두 이름을 로 바꾸고 if .avi
도 제거 하려는 경우 :[M][@0][0]
find . -name '*.dav.avi' -type f -exec sh -c '
for file do
new=${file%.*.*}
new=${new%"[M][@0][0]"}.avi
echo mv "$file" "$new"
done' sh +
이는 POSIX 구문이며 busybox 유틸리티와 함께 사용할 수도 있으므로 Synology에서 작동해야 합니다.
일부 참고 사항(본인 및 다른 답변의 관찰을 기반으로 함):
- 전달된 패턴은
find -name
인용되어야 합니다. 그렇지 않으면 셸에 의해 확장될 수 있습니다. xargs
공백, 개행, 따옴표 또는 백슬래시가 포함되어 있지 않다는 것을 보장할 수 없으면 파일 이름에 사용할 수 없습니다.printf
대신에echo
임의의 데이터를 출력하는 데 사용하십시오 ..- 목록 컨텍스트에서 따옴표가 없는 변수 확장을 유지하는 것은 매우 특별한 의미를 갖습니다.. 여기서는 그러고 싶지 않을 겁니다.
- 이
.
문자는 특수 정규식 연산자이므로 문자 그대로 처리하려면 정규식에서 이스케이프해야 합니다. - 한 줄을 읽는 구문
read
은 다음과 같습니다.IFS= read -r line
, 그러나 파일 경로가 한 줄로만 구성된다는 보장은 없습니다. (cd -P -- "$dir" && find . ... -exec)
이는 일반적으로 and로 시작하는 조건 자나 값find -- "$dir" ... -exec
의 문제를 방지 하고 에 전달되는 파일 경로를 단축하여 더 많은 콘텐츠를 전달할 수 있기 때문에 이 방법보다 더 좋습니다 .$dir
find
-
-exec
답변2
sed
이름이 바뀐 파일을 사용하는 빠른 솔루션은 다음과 같습니다 .
echo "10.01.07-10.01.48[M][@0][0].dav.avi" | sed 's/\[.*dav//'
10.01.07-10.01.48.avi
Synology 셸에 대해 아무것도 모르지만 sed
작동하길 바랍니다!
루프에서 사용됩니다(예:):
#!/bin/sh
for file in *avi; do
newName=$(echo "$file" | sed 's/\[.*dav//')
mv -v "$file" "$newName"
done
앞으로:
ls
09.01.07-13.11.48[M][@0][0].dav.avi
110.01.07-13.11.48[M][@0][0].dav.avi
12.01.07-13.11.48[M][@0][0].dav.avi
스크립트를 실행합니다:
./renameAvi.sh
”09.01.07-13.11.48[M][@0][0].dav.avi” -> ”09.01.07-13.11.48.avi”
”110.01.07-13.11.48[M][@0][0].dav.avi” -> ”110.01.07-13.11.48.avi”
”12.01.07-13.11.48[M][@0][0].dav.avi” -> ”12.01.07-13.11.48.avi”
뒤쪽에:
ls
09.01.07-13.11.48.avi 12.01.07-13.11.48.avi
110.01.07-13.11.48.avi
편집하다:
사용하고 싶다면find
하나이는 다음과 같이 달성됩니다.
find . -name "*.avi" | while read fileName; do newName=$(echo "$fileName" | sed 's/\[.*dav//'); mv -v "$fileName" "$newName"; done
”./01.01.07-13.11.38[M][@0][0].dav.avi” -> ”./01.01.07-13.11.38.avi”
”./01.01.07-13.11.39[M][@0][0].dav.avi” -> ”./01.01.07-13.11.39.avi”
sed --version
sed (GNU sed) 4.2.2
find --version
find (GNU findutils) 4.4.2
답변3
재귀적으로 파일 이름을 바꾸려면 다음 명령을 사용해야 합니다.
find . -name "*dav.avi" | while read fileName; do newName=$(echo "$fileName" | sed 's/\[.*dav//'); mv -v "$fileName" "$newName"; done
위 스크립트에서 변경됨
(위의 설명을 추가할 수 없으므로 maulinglawns에서 이미 언급한 스크립트를 약간 변경하여 여기에 답변을 추가합니다)
- Synology 저장소에 많은 반복 파일이 있으므로 *dav.avi를 검색하는 데 사용합니다. 따라서 이 파일의 이름을 바꾼 후에는 다시 이름을 바꿔야 합니다.
- 이는 작은 변화이지만 실제 시스템에 ~GB의 데이터 파일이 있는 경우 영향을 미칩니다.
답변4
마침내 해결책을 찾았습니다. 이름 바꾸기는 두 단계로 수행됩니다. 이는 다른 CCTV 녹화기가 다른 이름으로 파일을 전송할 수 있지만 항상 DAV 형식이기 때문입니다. 따라서 다른 유형의 로거와 함께 작동하려면 두 번째 줄과 유사한 줄을 추가하면 됩니다.
find $katalog -type f -name *.dav.avi | sed -e "p;s/.dav.avi/\.avi/" | xargs -n2 mv 2>/dev/null
find $katalog -type f -name *.avi | sed -e "p;s/\[M\]\[@0\]\[0\].avi/\.avi/" | xargs -n2 mv 2>/dev/null