작업은 n+1개의 인수를 사용하는 쉘 스크립트를 작성하는 것입니다. 여기서 첫 번째 인수는 디렉토리이고 나머지는 지정된 파일이며 지정된 파일을 제외한 모든 파일을 삭제합니다.
예를 들어 전화를 걸어보세요.rmexcept . '*.jpg' '*.png'
cd $1
for i in “${@:2}”
do
find . -type f -not -name $i -delete
done
이것이 나의 시도이다. 그러나 지정된 파일 1개(예 rmexcept . '*.jpg'
: )에 대해서만 작동합니다. 파일이 2개 이상인 경우(예 rmexcept . '*.jpg' '*.png'
: ) 모든 파일이 삭제됩니다. for 루프를 생성했다고 믿기 때문에 무엇이 잘못되고 있는지 모르겠습니다.
답변1
이것을 시도해 보십시오(댓글은 인라인):
#!/bin/bash
set -f # Prevent e.g. *.txt from being expanded here
dir=$1 # Get the target directory and
shift # remove from list of args
cmd="find $dir -type f"
while (( "$#" )) # While there are more arguments left
do
cmd="$cmd -not -name $1" # add to not match
shift # and remove from list of arguments
done
cmd="$cmd -exec rm -i {} ;" # finally execute rm on the remaining matches
echo $cmd # Print the final find command
$cmd # And execute it
각 파일을 삭제하기 전에 묻도록 -i
추가 했습니다 . rm
하지만 물론 조정할 수 있습니다.
답변2
동일한 메커니즘란케이오답변, 그러나 변수가 없는 최소한의 방법으로POSIX쉘 기능:
rmexcept(){ find "$1" $(shift; printf " -not -name %s" ${@}) -exec rm '{}' \; ;}
쉘 명령은 또는 루프
printf
대신 주요 작업을 수행합니다 .for
while
bash
쉘을 사용하면shift
이는 매개변수 확장으로 대체될 수 있습니다.rmexcept(){ find "$1" $(printf " -not -name %s" ${@:2}) -exec rm '{}' \; ;}
find
결과나 rm
명령이 반환된 숫자보다 길면 두 함수 모두 작업을 완료하지 않습니다 getconf ARG_MAX
. 바라보다:Bash 명령줄 및 입력 제한 사항.