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実際にファイルを削除します。ファイルの数は同じかもしれませんが、リストにない名前のファイルがまだ存在する可能性があることを考えると、あまり意味がないように見えるため、ファイルの数が異なることを確認していません。

関連情報