実行は自己責任でお願いします!( . から始まるファイルも消えます)
bash
# bash のワイルドカードによるパス名展開を無効化(/* 対策)
# find による正規表現の解釈も perl で無効化
alias del='set -f && DelEx'
# 正規表現について
# "." :任意の1文字
# "*" :直前の文字に0回以上マッチ(最長一致)
# "|" :OR条件
function DelEx () {
set +o noglob
set -o nounset
ErrMsg="This function requires arguments."
Usage="Usage: del <path> [<name to exclude> <name to exclude> ...]"
! (: ${1:?"${ErrMsg}${IFS}${Usage}${IFS}"}) && return 1
Path="$1"
Path="$(realpath -- "$Path")"
[[ "$Path" == "/" ]] && {
echo "Cannot execute.";
return 1;
}
unset Arg Args
N=2; Arg=(); Args=()
while [[ "$N" -le "$#" ]]; do
Arg[$N]="$N"
Escaped=$(perl -e "print quotemeta('${!Arg[$N]}');")
Args+=(! -regex ".*/${Escaped}\(/.*\|\)")
((N++))
done
[[ -d $Path ]] && {
[[ $1 =~ ^\.+(/+\.*)*$ ]] || { find "$Path" -xdev -maxdepth 0 -delete 2>/dev/null && return; }
find "$Path" -xdev -depth ! -path "$Path" -regextype findutils-default "${Args[@]}" -delete 2> >(grep -v "Directory not empty" >&2);
return;
}
[[ -f $Path ]] && {
find "$Path" -xdev -maxdepth 0 -delete;
return;
}
return 255
}
bash
# 実行例
mkdir -p ./target/{"delete folder","exclude folder",other_folder}
touch ./target/{'.*[a-z]+',.file1,.file2} ./target/"delete folder"/{file3,file4} ./target/"exclude folder"/{file5,file6} ./target/other_folder/{file7,file8}
tree -a ./target
./target
├── .*[a-z]+
├── .file1
├── .file2
├── delete folder
│ ├── file3
│ └── file4
├── exclude folder
│ ├── file5
│ └── file6
└── other_folder
├── file7
└── file8
3 directories, 9 files
set -x
del ./target .*[a-z]+ "exclude folder" file8
set +x
tree -a ./target
./target
├── .*[a-z]+
├── exclude folder
│ ├── file5
│ └── file6
└── other_folder
└── file8
2 directories, 4 files
# 実行結果
del ./target .*[a-z]+ "exclude folder" file8
+ set -f
+ DelEx ./target '.*[a-z]+' 'exclude folder' file8
+ set +o noglob
+ set -o nounset
+ ErrMsg='This function requires arguments.'
+ Usage='Usage: del <path> [<name to exclude> <name to exclude> ...]'
+ : ./target
+ Path=./target
++ realpath -- ./target
+ Path=/home/$(whoami)/target
+ [[ /home/$(whoami)/target == \/ ]]
+ unset Arg Args
+ N=2
+ Arg=()
+ Args=()
+ [[ 2 -le 4 ]]
+ Arg[$N]=2
++ perl -e 'print quotemeta('\''.*[a-z]+'\'');'
+ Escaped='\.\*\[a\-z\]\+'
+ Args+=(! -regex ".*/${Escaped}\(/.*\|\)")
+ (( N++ ))
+ [[ 3 -le 4 ]]
+ Arg[$N]=3
++ perl -e 'print quotemeta('\''exclude folder'\'');'
+ Escaped='exclude\ folder'
+ Args+=(! -regex ".*/${Escaped}\(/.*\|\)")
+ (( N++ ))
+ [[ 4 -le 4 ]]
+ Arg[$N]=4
++ perl -e 'print quotemeta('\''file8'\'');'
+ Escaped=file8
+ Args+=(! -regex ".*/${Escaped}\(/.*\|\)")
+ (( N++ ))
+ [[ 5 -le 4 ]]
+ [[ -d /home/$(whoami)/target ]]
+ [[ ./target =~ ^\.+$ ]]
+ [[ ./target =~ ^\.+(/+\.*)+$ ]]
+ find /home/$(whoami)/target -xdev -maxdepth 0 -delete
+ find /home/$(whoami)/target -xdev -depth '!' -path /home/$(whoami)/target -regextype findutils-default '!' -regex '.*/\.\*\[a\-z\]\+\(/.*\|\)' '!' -regex '.*/exclude\ folder\(/.*\|\)' '!' -regex '.*/file8\(/.*\|\)' -delete
++ grep --color=auto -v 'Directory not empty'
+ return