x 시퀀스가 포함된 약 15,000개의 이미지가 있는 디렉토리가 있습니다.
scene1_000000.png
scene1_000001.png
scene1_000002.png
scene1_000003.png
scene1_000004.png
scene1_000005.png
scene1_000006.png
scene1_000007.png
scene1_000008.png
.
.
.
.
scene2_000300.png
scene2_000000.png
scene2_000001.png
scene2_000002.png
scene2_000003.png
scene2_000004.png
scene2_000005.png
scene2_000006.png
scene2_000007.png
scene2_000008.png
.
.
.
.
scene2_000300.png
.
.
.
.
scene50_000000.png
scene50_000001.png
scene50_000002.png
scene50_000003.png
scene50_000004.png
scene50_000005.png
scene50_000006.png
scene50_000007.png
scene50_000008.png
.
.
.
.
scene50_000300.png
각 시퀀스의 처음 150개 시퀀스를 유지하고 나머지는 삭제하고 싶습니다. 그래서 각 장면에 000000부터 000150까지의 시퀀스를 제공하겠습니다.
답변1
최신 버전의 bash에서는 중괄호 확장을 사용하여 이를 달성할 수 있습니다.
rm scene*_{000151..000300}.png
Bash의 중괄호 확장은 선행 0을 처리합니다.
$ echo {000000..000005}.png
000000.png 000001.png 000002.png 000003.png 000004.png 000005.png
따라서 이를 사용 {000151..000300}
하여 필요한 파일 목록을 생성할 수 있습니다.
답변2
사용 find
:
find . -maxdepth 1 -type f \
-name 'scene*.png' \
! -name '*_0000[0-9][0-9].png' \
! -name '*_0001[0-4][0-9].png' \
! -name '*_000150.png' -print -delete
현재 디렉터리에서만 삭제하려는 모든 파일을 찾습니다.
다양한 -name
플래그가 다음 작업을 수행합니다.
- 일치하는 항목만 선택하세요
scene*.png
. - 범위 내의
000000.png
파일 이름을 필터링(선택 항목에서 제거)합니다000099.png
. - 범위 내의
000100.png
파일 이름을 필터링합니다000149.png
. - 필터링하세요
000150.png
.
...그런 다음 파일을 삭제합니다(여전히 고려 중인 경우). 이러한 파일(우리가 보관하려는 파일)이 삭제되는 것을 방지하기 위해 두 번째, 세 번째 및 네 번째 -name
테스트는 무효화됩니다 .find
실제 삭제가 발생하기 전에 삭제된 파일의 이름도 인쇄됩니다.
먼저 삭제하고 실행하는 것이 좋습니다 -delete
.
답변3
존재하다지쉬,이 <m-n>
구문은 m과 n 사이의 숫자 문자열과 일치합니다. 둘 다 선택 사항입니다. 그러므로:
rm scene<->_<151->.png
scene*_
(와일드카드로 시작할 수도 있지만 이렇게 하면 다른 패턴에 따라 이름이 지정된 파일이 있는 경우 <->
예상치 못한 내용이 일치하는 것을 방지할 수 있습니다 .)*
답변4
약간의 스크립트일 수도 있습니다.
echo '#!/bin/bash
# Test argument
if [ $# = 1 ]; then
if [ -d $1 ]; then
cd $1
else
echo "$1 is not a directory" >&2
exit 1
fi
fi
declare f # filname
declare -i fc # file counter
declare -i fcs # file conter for a scene
declare sn # scene number
declare csn # current scene number
declare -i dfc # delete file counter
declare -i pfc # preserve file counter
# Open logfiles
exec file-delete>>&3
exec file-preserve>>&4
for f in *; do
((fc++))
sn=${f#scene}
sn=${sn%_*}
if [ "$sn" = "$csn" ]; then
((fcs++))
else
# New number scene
fcs=1
csn=$sn
dfc=0
pfc=0
echo
fi
if ((fcs > 150));then
# Candidate for deleting
echo "$f" >>&3
((dfc++))
else
# Preserve file
echo "$f" >>&4
((pfc++))
fi
# Display in console
echo -en "\r scene $csn preserve:$pfc delete:$dfc"
done
echo
# Closing logfile
exec 3>&-
exec 4>&-
echo "Files scaned : $fc"
wc -l file-delete
wc -l file-preserve
' > ~/scanfile
실행하세요:
bash ~/scanfile [<pathdir>]
생략하면 현재 디렉터리에서 작동합니다.
아무것도 삭제하지 않고 스캔된 디렉터리에 두 개의 파일(삭제된 파일과 보관된 파일)을 씁니다.
확인한 후 다음 명령을 사용하여 삭제하려는 파일을 이동할 수 있습니다.
[cd <pathdir>]
mkdir tmp
while read; do mv -v $REPLY tmp; done < file-delete
결과가 좋다면
rm -rf tmp
rm file-delete file-preserve