我想在 Mac 终端中使用正则表达式删除文件夹。
0129_0140 (no delete)
0140_0140 (delete)
0150_0160 (no delete)
0170_0170 (delete)
我只想删除 0140_0140 、 0170_0170 等文件夹。
(已添加)我想递归删除非空文件夹。
答案1
非递归
使用ksh93
(在 OS/X 上可用ksh
):
rmdir {4}(\d)_\1
{4}(\d)_\1
(请注意,如果没有与该模式匹配的文件,它可能会删除名为的目录)。
使用zsh
(在 OS/X 上可用zsh
):
setopt extendedglob
rmdir [0-9](#c4)_[0-9]##(/e:'[[ ${REPLY%_*} = ${REPLY#*_} ]]':)
(这个还有一个好处是只考虑类型的文件目录,使用/
上面的 glob 限定符)。
使用bash
或其他 POSIX shell(像sh
大多数系统的 shell 一样,包括OS/X
):
set -- [0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9]
for f do
[ "${f#*_}" = "${f%_*}" ] && set -- "$@" "$f"
shift
done
rmdir "$@"
(请注意,如果当前目录中[0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9]
没有文件,它可能会删除名为的目录)。XXXX_XXXX
使用find
和grep
:
find . ! -name . -prune -type d -name '[0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9]' |
grep -x '\./\(.*\)_\1' |
xargs rmdir
对于 BSD find
(如 OS/X 上所示):
find . -maxdepth 1 -regex './\([0-9]\{4\}\)_\1' -type d -delete
使用 GNU find
(通常在 OS/X 上找不到,除非通过 macports/homebrew/fink 安装...):
find . -maxdepth 1 -regextype grep -regex './\([0-9]\{4\}\)_\1' -type d -delete
递归地:
ksh93
:set -o globstar rmdir -- **/{4}(\d)\1
1111_1111
(请注意,如果有 a ,它不会删除,1111_1111/2222_2222
因为它会尝试先删除它1111_1111
不能删除的那个,因为2222_2222
其中有一个目录,ksh93
没有od
glob 限定符(对于深度优先顺序)zsh
)zsh
:setopt extendedglob rmdir -- **/[0-9](#c4)_[0-9]##(Dod/e@'[[ ${${REPLY:t}%_*} = ${REPLY##*_} ]]'@)
BSD
find
:LC_ALL=C find . -regex '.*/\([0-9]\{4\}\)_\1' -type d -delete
GNU
find
:LC_ALL=C find . -regextype grep -regex '.*/\([0-9]\{4\}\)_\1' -type d -delete
答案2
POSIX(删除echo
以echo rmdir
实际删除文件):
for dir in [0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9]/; do
a="$(expr "$dir" : '\(.*\)_\1/')"
${a:+false} || echo rmdir "$dir"
done
或者:
for d in [0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9]/; do
expr "$d" : '\(\(.*\)_\2\)/' >/dev/null && echo rmdir "$d"
done
或者:
set -- [0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9]/
for d
do expr "$d" : '\(\(.*\)_\2\)/' >/dev/null && echo rmdir "$d"
done
答案3
尝试这个:
find -type d -regextype posix-extended -regex '\./([0-9]{4})_\1' -delete
需要正则表达式类型设置{4}
。
答案4
一对简单的、符合 POSIX 标准的替代方案:
非递归(基本名称中不允许换行):
ls -F | grep '^\([0-9]\{4\}\)_\1/$' | xargs rm -fr
递归:
find . -type d -exec expr {} : '.*/\([0-9]\{4\}\)_\1$' \; -prune \
-exec rm -fr {} + >/dev/null