我有一个包含大约 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
标志执行以下操作:
- 只选择匹配的
scene*.png
。 - 过滤掉(从选择中删除)范围内的文件
000000.png
名000099.png
。 - 过滤掉 范围内的文件
000100.png
名000149.png
。 - 过滤掉以
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