删除所有以特定字符串结尾的文件

删除所有以特定字符串结尾的文件

我有一个包含大约 15K 图像的目录,其中有 x 个序列

scene1_000000.png
scene1_000001.png
scene1_000002.png
scene1_000003.png
scene1_000004.png
scene1_000005.png
scene1_000006.png
scene1_000007.png
scene1_000008.png
       .
       .
       .
       .
scene2_000300.png
scene2_000000.png
scene2_000001.png
scene2_000002.png
scene2_000003.png
scene2_000004.png
scene2_000005.png
scene2_000006.png
scene2_000007.png
scene2_000008.png
       .
       .
       .
       .
scene2_000300.png
       .
       .
       .
       .
scene50_000000.png
scene50_000001.png
scene50_000002.png
scene50_000003.png
scene50_000004.png
scene50_000005.png
scene50_000006.png
scene50_000007.png
scene50_000008.png
       .
       .
       .
       .
scene50_000300.png

我想保留每个序列的前 150 个序列,并删除其余的。所以我将为每个场景提供从 000000 到 000150 的序列

答案1

在最新版本的 bash 中,您可以使用大括号扩展来实现此目的:

rm scene*_{000151..000300}.png

Bash 的大括号扩展处理前导 0:

$ echo {000000..000005}.png
000000.png 000001.png 000002.png 000003.png 000004.png 000005.png

因此您可以使用它{000151..000300}来生成您需要的文件列表。

答案2

使用find

find . -maxdepth 1 -type f \
         -name 'scene*.png' \
       ! -name '*_0000[0-9][0-9].png' \
       ! -name '*_0001[0-4][0-9].png' \
       ! -name '*_000150.png' -print -delete

这将找到您想要在当前目录中删除的所有文件(仅)。

各种-name标志执行以下操作:

  1. 只选择匹配的scene*.png
  2. 过滤掉(从选择中删除)范围内的文件000000.png000099.png
  3. 过滤掉 范围内的文件000100.png000149.png
  4. 过滤掉以000150.png.

...然后删除该文件(如果仍然考虑)。第二、第三和第四个-name测试被否定,以阻止find删除这些文件(这些是我们想要保留的文件)。

在实际删除发生之前,还将打印已删除文件的名称。

我建议您-delete先删除并运行它。

答案3

兹什,<m-n>构造匹配 m 和 n 之间数字的字符串。两者都是可选的。因此:

rm scene<->_<151->.png

scene*_(您也可以使用通配符开头,但如果存在根据不同模式命名的文件,则<->可以防止匹配意外的内容)*

答案4

也许是一个小脚本:

echo '#!/bin/bash
# Test argument
if [ $# = 1 ]; then
  if [ -d $1 ]; then
    cd $1
  else
    echo "$1 is not a directory" >&2
    exit 1
  fi
fi

declare f      # filname
declare -i fc  # file counter
declare -i fcs # file conter for a scene
declare sn     # scene number
declare csn    # current scene number
declare -i dfc # delete file counter
declare -i pfc # preserve file counter

# Open logfiles
exec file-delete>>&3
exec file-preserve>>&4

for f in *; do
  ((fc++))
  sn=${f#scene}
  sn=${sn%_*}
  if [ "$sn" = "$csn" ]; then
    ((fcs++))
  else
    # New number scene
    fcs=1   
    csn=$sn
    dfc=0
    pfc=0
    echo
  fi
  if ((fcs > 150));then
    # Candidate for deleting
    echo "$f" >>&3
    ((dfc++))
  else
    # Preserve file
    echo "$f" >>&4
    ((pfc++))
  fi
  # Display in console
  echo -en "\r scene $csn preserve:$pfc delete:$dfc"
done
echo

# Closing logfile
exec 3>&-
exec 4>&-

echo "Files scaned : $fc"
wc -l file-delete
wc -l file-preserve
' > ~/scanfile

运行它:

bash ~/scanfile [<pathdir>]

如果省略,则在当前目录中工作。

它不会删除任何内容,而是在扫描目录中写入两个文件(文件删除和文件保留)。

检查后,可以使用以下命令移动要删除的文件:

[cd <pathdir>]
mkdir tmp
while read; do mv -v $REPLY tmp; done < file-delete

如果结果好的话

rm -rf tmp
rm file-delete file-preserve

相关内容