删除名称中出现两次 4 位数字的文件夹

删除名称中出现两次 4 位数字的文件夹

我想在 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

使用findgrep

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没有odglob 限定符(对于深度优先顺序)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(删除echoecho 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

相关内容