Bash - 「ユーザー入力から一致しない配列のみを削除する」関数を作成する方法

Bash - 「ユーザー入力から一致しない配列のみを削除する」関数を作成する方法

次のフォルダに1つのファイルがあるとします。B.py

このスクリプトを使用して、フォルダに3つのファイルを作成しました。これらのファイルはA.py B.py C.py

read -r -p "Enter the filenames: " -a arr
for filenames in "${arr[@]}"; do
   if [[ -e "${filenames}" ]]; then
        echo "${filenames} file exists (no override)"
   else
        cp -n ~/Documents/library/normal.py "${filenames}" && echo "${filenames} file created"
   fi
done

ここA.pyで、およびはテンプレートC.pyとして生成されますが変更されていません。normal.pyB.py

今私削除機能が欲しい A.pyそしてC.py(新しく作成されました)。
上書きされていない内容は削除されません。

これを配列でどのようにフィルタリングできますか?

PS:私はまだ初心者です。私のスクリプトではこの機能を実装できません。
スクリプトは次のように削除する必要がありますrm -i {A,C}.py

ここでこのスレッドを見ました。
Bash - 配列にないすべてのファイルを見つける方法

メモ:ユーザー入力は3つではなく定義されていません。

答え1

.py現在のディレクトリのすべてのファイルを削除したい場合正確なコピー~/Documents/library/normal.py次のようにすることができます:

for f in ./*.py; do
  if cmp ~/Documents/library/normal.py "$f"; then
    rm "$f"
  fi
done

cmpこれは、各ファイルを$fNormal.pyと比較するために使用されます。 "$ f"は、0(true)が返された場合にのみcmp削除されます。

man cmp詳細より。

~/Documents/library ディレクトリで実行しないように注意してください。これを防ぐバージョンは次のとおりです。


src_file=~/Documents/library/normal.py
src_dir=$(dirname "$src_file")

if [ "$(realpath -e ./)" = "$(realpath -e "$src_dir")" ] ; then
  echo "Warning: This script is NOT safe to run in the same directory as $src_file" >&2
  exit 1
fi

for f in ./*.py; do
  if cmp "$src_file" "$f"; then
    rm "$f"
  fi
done

答え2

次に切り替えるオプションが提供されている場合zsh

arr=()
# use vared instead of read for the user to be able to enter
# arbitrary file names including some with whitespace of newlines
# by using \ (and also allows some user friendly editing).
vared -p 'Enter the filenames: ' arr

files=(*(ND)) # files including hidden ones in the current directory

for file ${arr:|files}; do # loop over elements of arr *bar* those of files
  cp -n -- $template $file
done

次に、存在しないファイルを削除するには、$var次の手順を実行します。

rm -f -- ${files:|arr}

glob修飾子の一部として、ファイルが配列のメンバーであるかどうかを確認することもできます。

rm -f -- *.py(e['(( ! $arr[(Ie)$REPLY] ))'])

たとえば、名前で正確に見つからない配列要素は、非表示のファイルとして.py削除されます。e$arr

$arr[(I)pattern]パターンに一致する最後の配列要素のインデックスに展開されます。見つからない場合は0です。このeフラグは正確な一致(パターン一致なし)を実行します。

関連情報