나는 bash 스크립트를 작성 중이며 디렉토리의 파일 이름이 텍스트 파일에 나타나는지 알려주고 그렇지 않으면 삭제하도록 하고 싶습니다.
이 같은:
counter = 1
numFiles = ls -1 TestDir/ | wc -l
while [$counter -lt $numFiles]
do
if [file in TestDir/ not in fileNames.txt]
then
rm file
fi
((counter++))
done
답변1
파일 목록을 변수에 저장하는 대신 이름을 반복합니다.
for name in TestDir/*; do
# the rest of the code
done
$name
에 존재 하는지 테스트하려면 fileNames.txt
다음을 사용하세요 grep -q
.
for name in TestDir/*; do
if ! grep -qxF "$name" fileNames.txt; then
echo rm "$name"
fi
done
make는 정규식 일치 대신 문자열 비교를 수행합니다. 사용하면 -F
출력은 없고 명령문과 함께 사용할 수 있는 종료 상태만 얻습니다(문자열이 발견되면 true이지만 느낌표는 테스트의 의미를 반전시킵니다). 문자열이 줄의 일부가 아니라 처음부터 끝까지 줄 전체와 일치해야 함을 나타냅니다.grep
-q
grep
if
-x
grep
$name
rm
나는 실제로 protected를 사용했습니다 echo
. 실행하여 올바른 파일이 삭제되었는지 확인하세요.
TestDir
파일 이름이 경로 없이 나열되면 $name
명령을 grep
다음으로 변경합니다 ${name##*/}
.
for name in TestDir/*; do
if ! grep -qxF "${name##*/}" fileNames.txt; then
echo rm "$name"
fi
done
$name
.dll을 포함한 전체 경로가 아닌 경로의 파일 이름 부분을 찾습니다 TestDir
.
답변2
그리고 zsh
:
expected=(${(f)"$(<fileNames.txt)"}) || exit
cd TestDir || exit
actual=(*(D))
superfluous=(${actual:|expected})
if (($#superfluous)) {
echo These files are not in the expected list:
printf ' - %q\n' $superfluous
read -q '?Do you want to delete them? ' && rm -rf -- $superfluous
}
답변3
귀하의 방법을 사용하는 작업 버전은 다음과 같습니다.
#!/bin/bash
fileList="$1"
targetDir="$2"
## Read the list of files into an associative array
declare -A filesInFile
while IFS= read -r file; do
filesInFile["$file"]=1
done < "$fileList"
## Collect the files in the target dir
filesInDir=("$targetDir"/*);
for file in "${filesInDir[@]}"; do
file=${file##*/}; # get the name of the file; remove path
## If this file has no entry in the array, delete
if [[ -z "${filesInFile[$file]}" ]]; then
echo "rm $file"
fi
done
삭제는 echo
실제로 파일을 삭제합니다. 파일 수가 동일할 수 있지만 목록에 없는 이름의 파일이 여전히 있을 수 있다는 점을 고려하면 별 의미가 없는 것 같기 때문에 파일 수가 다른지 확인하지 않았습니다.