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