if 문은 파일이 디렉터리에 있는지 여부를 결정합니다.

if 문은 파일이 디렉터리에 있는지 여부를 결정합니다.

나는 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-qgrepif-xgrep$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실제로 파일을 삭제합니다. 파일 수가 동일할 수 있지만 목록에 없는 이름의 파일이 여전히 있을 수 있다는 점을 고려하면 별 의미가 없는 것 같기 때문에 파일 수가 다른지 확인하지 않았습니다.

관련 정보