xシーケンスを含む約15,000の画像を含むディレクトリがあります。
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の中括弧拡張は先行ゼロを処理します。
$ 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
。
...その後、ファイルを削除します(まだ考慮している場合)。これらのファイル(私たちが保持したいファイル)が削除されるのを防ぐために、2番目、3番目、4番目のテストは-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>]
省略すると、現在のディレクトリで動作します。
何も削除せずに、スキャンしたディレクトリに2つのファイル(削除されたファイルとアーカイブされたファイル)を書き込みます。
確認したら、次のコマンドを使用して削除したいファイルを移動できます。
[cd <pathdir>]
mkdir tmp
while read; do mv -v $REPLY tmp; done < file-delete
結果が良ければ
rm -rf tmp
rm file-delete file-preserve